一、原理
Spring里的动态代理通过aop实现,aop通过封装asm,CGLib包实现对动态代理的封装,又借助注解的方式省略了动态代理所需的动态类创建的编写,只需写出前增强和后增强的方法加上注释即可。
二、实现
例如乘法方法:
@Override
public int mul(int a, int b) {
System.out.println(this.getClass().getName()+":The mul method begins.");
System.out.println(this.getClass().getName()+":Parameters of the mul method: ["+a+","+b+"]");
int result = a*b;
System.out.println(this.getClass().getName()+":The mul method ends.");
return result;
}
很明显关键部分只有这一行代码 int result = a*b;前面可以说前增强,后面可以说后增强。
至于实现首先第一步对Spring而言需要添加两个新的jar包aspectjweaver-1.8.10.jar和spring-aop-4.3.10.RELEASE.jar。
然后创建Spring Bean Configuration File(命名为application.xml并且下一步中勾选aop),在application.xml里NameSpaces勾选aop,并在Source处添加这样一行代码 <aop:aspectj-autoproxy proxy-target-class="false"></aop:aspectj-autoproxy>。(注:proxy-target-class默认值为false,代表使用JDK动态代理,在getBean方法里面的目标类class需要转换为接口类class,若修改值为false,写目标类即可)
接下来创建代理类,然后加上注解@Aspect(表明该类为切面类)
@Component(表明此类在Spring运行时自动创建对象)
接下来写前增强方法
首先在方法前加注释@Before("execution(返回类型 方法名(..))"),然后为方法添加JoinPoint jp参数,再通过jp的getTarget()、getArgs()、getSignature().getName()这三个方法分别获取对应方法的目标类,参数数组,方法名
Object object = jp.getTarget();
Object [] args =jp.getArgs();
String name = jp.getSignature().getName();。然后通过这些将前增强代码替换写入,例如:
System.out.println(object.getClass().getName()+":The "+name+" method begins.");
System.out.println(object.getClass().getName()+":Parameters of the "+name+" method: ["+args[0]+","+args[1]+"]");
后增强只需把注释里面的Before修改为After。
三、执行过程
Spring寻找@Aspect类(CalculatorAspect)——>寻找该类中方法——>获取方法注解 ——> 获取表达式(execution(int mul(int a, int b))——>检查Spring能扫描到的所有类,将与表达式匹配的方法对应的类——>为该类创建动态对象-->