AOP配置文件版(Spring基础-06为注解版)
MyMathCalculator.java:
package com.atguigu.impl; import org.springframework.stereotype.Service; /** * @Title: MyMathCalculator * @Description: * @Author: * @Version: 1.0 * @create 2020/6/7 19:43 */ public class MyMathCalculator /*implements Calculator*/ { //@Override public int add(int i, int j) { //System.out.println("【add】方法开始了,它使用的参数是:【"+i+"】,【"+j+"】"); //考虑方法的兼容性 //LogUtils.logStart(i, j); int result = i + j; // System.out.println("【add】方法运行完成,计算结果是:【"+result+"】"); System.out.println("方法内部执行"); return result; } //@Override public int sub(int i, int j) { int result = i - j; System.out.println("方法内部执行"); return result; } //@Override public int mul(int i, int j) { int result = i * j; System.out.println("方法内部执行"); return result; } //@Override public int div(int i, int j) { int result = i / j; System.out.println("方法内部执行"); return result; } }
Calculator.java:
package com.atguigu.inter; /** * 接口不加载在容器中 * 实际上可以加,加了也不创建对象,只要一看这个组件是一个接口, * 相当于告诉Spring,ioc容器中可能有这种类型的组件 */ public interface Calculator { public int add(int i, int j); public int sub(int i, int j); public int mul(int i, int j); public int div(int i, int j); }
LogUtils.java:
package com.atguigu.utils; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.Signature; import org.aspectj.lang.annotation.*; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import java.util.Arrays; public class LogUtils { public static void logStart(JoinPoint joinPoint) { //获取目标方法运行时使用的参数 Object[] args = joinPoint.getArgs(); //获取到方法签名 Signature signature = joinPoint.getSignature(); String name = signature.getName(); System.out.println("[LogUtils-前置][" + name + "]方法开始执行,使用的参数列表" + Arrays.asList(args)); } public static void logReturn(JoinPoint joinPoint, Object result) { Signature signature = joinPoint.getSignature(); String name = signature.getName(); System.out.println("[LogUtils-返回][" + name + "]方法正常执行完成了,计算结果是" + result); } public static void logException(JoinPoint joinPoint, Exception exception) { System.out.println("[LogUtils-异常][" + joinPoint.getSignature().getName() + "]方法出现异常了,异常信息是:[" + exception + "],这个异常已经通知测试测试小组进行排查"); } public static int logEnd(JoinPoint joinPoint) { System.out.println("[LogUtils-后置][" + joinPoint.getSignature().getName() + "]方法最终结束"); return 0; } public Object myAround(ProceedingJoinPoint pjp) throws Throwable { Object[] args = pjp.getArgs(); String name = pjp.getSignature().getName(); Object proceed = null; // idea ctrl + alt + t try { //利用反射调用目标方法即可,就是method.invoke(obj,args) //@Before System.out.println("[环绕前置通知]-[" + name + "方法开始]"); proceed = pjp.proceed(); //@AfterReturning System.out.println("[环绕返回通知]-[" + name + "方法返回,返回值为:" + proceed + "]"); } catch (Exception e) { //@AfterThrowing System.out.println("[环绕异常通知]-[" + name + "方法出现异常],异常信息" + e.getCause()); //为了让外界能知道这个异常,这个异常一定要抛出去 throw new RuntimeException(e); } finally { //@After System.out.println("[环绕后置通知最终结束]-[" + name + "]方法结束"); } //反射调用后的返回值也一定返回出去 return proceed; } }
ValidateAspect.java:
package com.atguigu.utils; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.Signature; import org.aspectj.lang.annotation.*; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import java.util.Arrays; /** * @Title: ValidateApsect * @Description: * @Author: * @Version: 1.0 * @create 2020/6/8 11:53 */ public class ValidateAspect { public void logStart(JoinPoint joinPoint) { //获取目标方法运行时使用的参数 Object[] args = joinPoint.getArgs(); //获取到方法签名 Signature signature = joinPoint.getSignature(); String name = signature.getName(); System.out.println("[VaAspect-前置][" + name + "]方法开始执行,使用的参数列表" + Arrays.asList(args)); } public void logReturn(JoinPoint joinPoint, Object result) { Signature signature = joinPoint.getSignature(); String name = signature.getName(); System.out.println("[VaAspect-返回][" + name + "]方法正常执行完成了,计算结果是" + result); } public void logException(JoinPoint joinPoint, Exception exception) { System.out.println("[VaAspect-异常][" + joinPoint.getSignature().getName() + "]方法出现异常了,异常信息是:[" + exception + "],这个异常已经通知测试测试小组进行排查"); } public int logEnd(JoinPoint joinPoint) { System.out.println("[VaAspect-后置][" + joinPoint.getSignature().getName() + "]方法最终结束"); return 0; } }
applicationContext.xml:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xmlns:aop="http://www.springframework.org/schema/aop" 6 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"> 7 8 <context:component-scan base-package="com.atguigu"></context:component-scan> 9 10 <!--基于注解的AOP步骤 11 1.将目标类和切面类都加入到ioc容器中 12 2.告诉spring哪个是切面类 @Aspect 13 3.在切面类中使用5个通知注解来配置切面中的这些方法何时何地运行 14 4.开启基于注解的AOP功能 15 --> 16 17 <!--开启基于注解的AOP功能:AOP名称空间--> 18 <!--<aop:aspectj-autoproxy></aop:aspectj-autoproxy>--> 19 20 <!--基于配置的AOP--> 21 <bean class="com.atguigu.impl.MyMathCalculator" id="myMathCalculator"></bean> 22 <bean class="com.atguigu.utils.ValidateAspect" id="validateAspect"></bean> 23 <bean class="com.atguigu.utils.LogUtils" id="logUtils"></bean> 24 25 <!--需要AOP名称空间--> 26 <aop:config> 27 <!--全局--> 28 <aop:pointcut id="globalPoint" expression="execution(* com.atguigu.impl.*.*(..))"/> 29 30 <!--普通前置 ———— 目标方法 ——(环绕执行后置/返回)——普通后置 ———— 普通返回 --> 31 <!--指定切面 @Aspect--> 32 <!--按照配置顺序进行切入,可以使用order进行修改--> 33 <aop:aspect ref="logUtils" order="3"> 34 <!--配置哪个方法是前置通知 method指定方法名 35 logStart @Before("切入点表达式") 36 --> 37 <!--当前切面能用的--> 38 <aop:around method="myAround" pointcut-ref="globalPoint"/> 39 <aop:pointcut id="myPoint" expression="execution(* com.atguigu.impl.*.*(..))"/> 40 <aop:before method="logStart" pointcut="execution(* com.atguigu.impl.*.*(..))"/> 41 <aop:after-returning method="logReturn" pointcut-ref="myPoint" returning="result"/> 42 <aop:after-throwing method="logException" pointcut-ref="myPoint" throwing="exception"/> 43 <aop:after method="logEnd" pointcut-ref="myPoint"/> 44 </aop:aspect> 45 <aop:aspect ref="validateAspect"></aop:aspect> 46 <!--在切面类中使用5个通知注解来配置切面中的这些方法何时何地运行--> 47 48 <aop:aspect ref="validateAspect" order="-1"> 49 <aop:before method="logStart" pointcut-ref="globalPoint"/> 50 <aop:after-returning method="logReturn" pointcut-ref="globalPoint" returning="result"/> 51 <aop:after-returning method="logReturn" pointcut-ref="globalPoint" returning="result"/> 52 <aop:after-throwing method="logException" pointcut-ref="globalPoint" throwing="exception"/> 53 <aop:after method="logEnd" pointcut-ref="globalPoint"/> 54 </aop:aspect> 55 </aop:config> 56 57 <!-- 58 总结: 59 注解:快速方便 60 配置:功能完善,重要的用配置,不重要的用注解 61 --> 62 63 </beans>
AOPTest.java:
package com.atguigu.test; import com.atguigu.impl.MyMathCalculator; import com.atguigu.inter.Calculator; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * @Title: AOPTest * @Description: * @Author: * @Version: 1.0 * @create 2020/6/7 23:35 */ //@ContextConfiguration(locations = "classpath:applicationContext.xml") //@RunWith(SpringJUnit4ClassRunner.class) public class AOPTest { ApplicationContext ioc = new ClassPathXmlApplicationContext("classpath:applicationContext.xml"); @Test public void test(){ MyMathCalculator bean = ioc.getBean(MyMathCalculator.class); bean.add(1,2); System.out.println("============"); // bean.div(1,0); bean.div(1,1); } }