这次来浅谈一下注解spring AOP 的源码,在spring底层代码中,作为开启注解AOP的 @EnableAspectJAutoProxy 究竟干了些啥。
本文章记录的是博主学习aop源码的一些理解,如果有错,望指出
@EnableAspectJAutoProxy的代码历程
1. 是个啥?
它,长这样:
这里重点是 @Import(AspectJAutoProxyRegistrar.class),导入了 AspectJAutoProxyRegistrar.class。
AspectJAutoProxyRegistrar类
进入这个类中,在注释中发现这个类是用来将 AnnotationAwareAspectJAutoProxyCreator 这个类注册到 BeanDefinitionRegistry 里。
AnnotationAwareAspectJAutoProxyCreator 这个类是什么呢?这里先不说,在后面更新的文章中会详细讲解。
那么,这个类要怎么把 AnnotationAwareAspectJAutoProxyCreator 这个类注册到 BeanDefinitionRegistry 里的呢?
继续往下看,可以看到该类中重写了一个方法:
这里关注一下圈起来的代码,这个代码的意思大概是“如果需要的话就注册AspectJAnnotationAutoProxy的创造者”。点进去之后会发现方法内又调用了与该方法重名的另一个方法:
圈起来的代码的大意是“注册或升级xxx(我也不懂)”,然后传入了上面提到的 AnnotationAwareAspectJAutoProxyCreator.class,此时继续进去看看发生了什么。
@Nullable
private static BeanDefinition registerOrEscalateApcAsRequired(
Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
/** 直接看这里
这里是判断bean的定义工厂registry中有没有
AUTO_PROXY_CREATOR_BEAN_NAME ="org.springframework.aop.config.internalAutoProxyCreator"
第一次运行项目时是没有的,结果为 false
*/
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
int requiredPriority = findPriorityForClass(cls);
if (currentPriority < requiredPriority) {
apcDefinition.setBeanClassName(cls.getName());
}
}
return null;
}
/**
此时代码执行到这里;
下方的代码都是在向bean定义工厂中注册
AnnotationAwareAspectJAutoProxyCreator,并且该类的名称设置为
org.springframework.aop.config.internalAutoProxyCreator,
由此:internalAutoProxyCreator = AnnotationAwareAspectJAutoProxyCreato
*/
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
beanDefinition.setSource(source);
beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
return beanDefinition;
}
代码执行完之后,registry 中已经存在了 AnnotationAwareAspectJAutoProxyCreator 的定义。
注意:这时,AnnotationAwareAspectJAutoProxyCreator 只是在bean工厂中定义了,还没有创建对象。
到此,@EnableAspectJAutoProxy 做了一件事,将 AnnotationAwareAspectJAutoProxyCreator 定义到了bean的工厂中(尚未创建对象)
2.AnnotationAwareAspectJAutoProxyCreator
分析继承关系如下
AnnotationAwareAspectJAutoProxyCreator
-> AspectJAwareAdvisorAutoProxyCreator
-> AbstractAdvisorAutoProxyCreator
-> AbstractAutoProxyCreato extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware
其中
ProxyProcessorSupport
-> extends ProxyConfig
implements Ordered, BeanClassLoaderAware, AopInfrastructureBean
SmartInstantiationAwareBeanPostProcesso
->InstantiationAwareBeanPostProcessor
-> BeanPostProcessor
BeanFactoryAware
->Aware
BeanClassLoaderAware
->Aware
在这些类中需要关注 3 个方法:
AbstractAutoProxyCreato.postProcessAfterInitializationj()
AbstractAutoProxyCreato.postProcessBeforeInstantiation()
AbstractAdvisorAutoProxyCreator.setBeanFactory()
这三个方法可以让我们在理解AOP代码的过程中起到很大的作用。
创建和注册
先定义一个增强类和被增强类并注入到IOC容器中,并打上断点
/**
* 告诉spring这个类是切面类(增强类)
*/
@Aspect
public class LogAspect {
/**
抽取切入点表达式
*
*/
@Pointcut("execution(* aopEntity.PlayGame.*(..))")
public void pointcut(){}
/**
*
前置通知
*/
@Before(value = "pointcut()")
public void logStart(){
System.out.println("前置通知执行。。。");
}
@After(value = "pointcut()")
public void logAfter(){
System.out.println("后置通知执行。。。");
}
@AfterReturning(value="pointcut()")
public void logReturning(){
System.out.println("返回通知执行。。。");
}
@AfterThrowing(value = "pointcut()")
public void logThrowing(){
System.out.println("异常通知执行。。。");
}
}
/**
被增强类
*/
public class PlayGame {
public void play(){
System.out.println("开始play。。。");
}
}
/**
* 开启基于注解的aop功能
*/
@EnableAspectJAutoProxy
@Configuration
public class AopConfig {
/**
* 将业务逻辑类加载到容器中
* 打上断点
* @return
*/
@Bean
public PlayGame playGame(){
return new PlayGame();
}
/**
* 将切面类加载到容器中
* 打上断点
*/
@Bean
public LogAspect logAspect(){
return new LogAspect();
}
}
步骤:
1、传入配置类,调用 refresh() 刷新容器
2、 调用 registerBeanPostProcessors(beanFactory) :注册拦截Bean创建的Bean处理器
3、 调用PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
4、 获取所有已经定义了需要获取对象的所有BeanPostProcessor
5、 分别给容器中添加实现了PriorityOrdered接口、Ordered接口、没实现以上接口的BeanPostProcessor
6、 注册实现Ordered接口的internalAutoProxyCreator(实际上就是AnnotationAwareAspectJAutoProxyCreator) ,。AnnotationAwareAspectJAutoProxyCreator 已经实现了Ordered 接口
getBean()调用流程:getBean()->doGetBean()->getSingleton()
6.1 、先给Bean赋值(populateBean()方法),然后创建并初始化bean实例
6.2、 执行Aware接口中的被实现的setBeanFactory()
6.3、 执行applyBeanPostProcessorsBeforeInitialization()。获取所有的后置处理器,调用每个后置处理器中的postProcessBeforeInitialization()
6.4、 执行自定义的初始化方法
6.5、 执行applyBeanPostProcessorsAfterInitialization。获取所有的后置处理器,调用每个后置处理器中的postProcessAfterInitialization()
7、 完成internalAutoProxyCreator(实际上就是AnnotationAwareAspectJAutoProxyCreator) 的初始化操作
8、 初始化BeanFactory,到此,AnnotationAwareAspectJAutoProxyCreator 创建成功。
8、 添加到已创建的bean的集合中。
9、 对beanPostProcessors进行排序和注册
到此,**AnnotationAwareAspectJAutoProxyCreator **创建注册完成。