上一章节主要介绍了JDK动态代理和CGLIB动态代理:https://www.cnblogs.com/GrimMjx/p/11194283.html
这一章主要结合我们之前学习的动态代理的基础来学习Sring AOP,本章学习需要Spring IOC的基础。首先会有一个Spring AOP的例子,后面逐渐深入会把一些关键的源码贴出来供大家学习。
二.一个栗子 2.1 创建Spring配置文件本例子使用xml的方式来配置Spring,如果你用Springboot可以用@EnableAspectJAutoProxy来开启AOP功能。xml配置Spring是否使用注解AOP的方式是<aop:aspectj-autoproxy/>,配置文件中有这句话Spring就会支持注解的AOP。
2.2 创建要被代理的bean这个bean的某个方法可能封装着核心逻辑,如果我们想对这个方法的前后加入日志或者其他逻辑进行增强,直接修改这个bean不符合面向对象的设计,还好Spring AOP帮我们做到这一点。那我们先创建一个简单的bean:
2.3 创建AdvisorSpring2.0可以采用@AspectJ注解对POJO进行标记,从而定义一个包含切点信息和增强横切逻辑的切面然后织入匹配的目标Bean中
在AspectJConfig中,我们简单的对test方法前后记录日志。记住光用@AspectJ注解是不够的。要么再添加@Component注解要么在xml添加这个bean,官方解释如下:
You may register aspect classes as regular beans in your Spring XML configuration, or autodetect them through classpath scanning - just like any other Spring-managed bean. However, note that the @Aspect annotation is not sufficient for autodetection in the classpath: For that purpose, you need to add a separate @Component annotation (or alternatively a custom stereotype annotation that qualifies, as per the rules of Spring’s component scanner).
再来看一下代码:
2.4 测试我们可以写一个简单的测试类,通过容器拿到TestBean这个bean,然后调用test方法,看一下结果:
三.源码赏析最好带着问题去看源码,要不然自己也是跟着走一遍,源码是无尽,开发思想是有尽的。比如今天看了ConcurrentHashMap的size方法对cas的优化,再看看LongAdder是咋玩的,学到了分散思想。
-谁来创建AOP的?
-谁来解析@Aspect注解的类?
-JDK动态代理怎么创建的?
-CGlib动态代理怎么创建的?
-有什么好的设计方式吗?
-等等
3.1 谁来创建?是AnnotationAwareAspectJAutoProxyCreator。(名字就很通俗易懂)
Spring扫到<aop:aspectj-autoproxy/>后,AspectJAutoProxyBeanDefinitionParser会注册这位创建者。对于Spring AOP的实现,AnnotationAwareAspectJAutoProxyCreator是负责代理的创建者,也是我们赏析的开始。先来看下这个创建者的类图:
当Spring加载每个Bean的时候会在实例化前调用postProcessorAfterInitialization方法,对于AOP的逻辑也由此开始:
3.2 获取所有增强器还记得之前的栗子吗?有个类是有@AspectJ注解的AspectJConfig类,这个类里面有@PointCut注解,这个注解的意思是对哪些方法进行增强,这里@Pointcut("execution(* *.test(..))")表示要对所有test方法进行增强。通过不同的切点表达函数可以实现对某些你想要类或者方法进行增强。
那么,什么叫增强器?Spring AOP在JoinPoint“周围”维护一系列的拦截器。有哪些Advice呢?
@Before - 在JoinPoint方法之前执行
@AfterReturning - 在JoinPoint方法正常执行后执行
@AfterThrowing - 在JoinPoint方法抛出异常退出并执行
@After - 无论JoinPoint方法正常返回还是异常返回都会执行
@Around - 在JoinPoint方法前后执行