Spring之AOP原理
首先看给容器中注册了什么组件,这个组件什么时候工作,这个组件的功能是什么?
(以@EnableAspectJAutoProxy为例:在容器中注册了AnnotationAwareAspectJAutoProxyCreator,然后再接着分析该组件的功能)
@EnableAspectJAutoProxy:开启基于注解的aop模式
所以从@EnableAspectJAutoProxy开始分析
Ⅰ、@EnableAspectJAutoProxy
-
@Import(AspectJAutoProxyRegistrar.class):给容器中导入AspectJAutoProxyRegistrar
- 利用AspectJAutoProxyRegistrar自定义给容器中注册beanDefinition;
(给容器中注册一个AnnotationAwareAspectJAutoProxyCreator;)
- key= internalAutoProxyCreator, value= AnnotationAwareAspectJAutoProxyCreator
在AspectJAutoProxyRegistrar中执行:
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
该方法调用以下方法:
若registry中没有internalAutoProxyCreator,则创建该类的BeanDefinition,并将其放入registry中
//AopConfigUtils //registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, null); private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) { Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); if (registry.containsBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator")) { //... //... } else { RootBeanDefinition beanDefinition = new RootBeanDefinition(cls); beanDefinition.setSource(source); beanDefinition.getPropertyValues().add("order", -2147483648); beanDefinition.setRole(2); registry.registerBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator", beanDefinition); return beanDefinition; } }
Ⅱ、AnnotationAwareAspectJAutoProxyCreator
AspectJ自动代理的创建器
1、分析
AnnotationAwareAspectJAutoProxyCrCeator
->AspectJAwareAdvisorAutoProxyCreator
->AbstractAdvisorAutoProxyCreator
->AbstractAutoProxyCreator
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware
关注后置处理器(在bean初始化完成前后做事情)、BeanFactoryAware自动装配BeanFactory
-> :继承或实现
根据继承树从上往下分析:(找出与后置处理器、BeanFactory相关的方法并打上断点)
- AspectJAwareAdvisorAutoProxyCreator:
- postProcessAfterInitialization
- postProcessBeforeInstantiation
- setBeanFactory
- AbstractAdvisorAutoProxyCreator
- setBeanFactory 重写了父类的方法,不用再看父类的setBeanFactory
- this.initBeanFactory((ConfigurableListableBeanFactory)beanFactory);
- initBeanFactory
- setBeanFactory 重写了父类的方法,不用再看父类的setBeanFactory
- AspectJAwareAdvisorAutoProxyCreator
- 没有相关的方法
- AnnotationAwareAspectJAutoProxyCrCeator
- initBeanFactory 重写
2、调试
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfAOP.class);
流程:
1.传入配置类(MainConfigOfAOP),创建ioc容器
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
this();
this.register(annotatedClasses);
this.refresh();
}
2.注册配置类(register方法),调用refresh()刷新容器 --> 实例化所有bean
3.refresh()中调用invokeBeanFactoryPostProcessors(beanFactory):详见ioc源码
4.refresh()中调用registerBeanPostProcessors(beanFactory):注册bean的后置处理器来方便拦截bean的创建;
1、先获取ioc容器已经定义了的需要创建对象的所有BeanPostProcessor
2、给容器中加别的BeanPostProcessor
3、优先注册实现了PriorityOrdered接口的BeanPostProcessor;
4、再给容器中注册实现了Ordered接口的BeanPostProcessor;
5、注册没实现优先级接口的BeanPostProcessor;
6、注册BeanPostProcessor,实际上就是创建BeanPostProcessor对象,保存在容器中;
创建internalAutoProxyCreator的BeanPostProcessor【AnnotationAwareAspectJAutoProxyCreator】
-
创建Bean的实例
-
populateBean;给bean的各种属性赋值
-
initializeBean:初始化bean;
1) invokeAwareMethods():处理Aware接口的方法回调
判断 bean instanceof BeanFactoryAware ===执行> setFactory方法 (结合第一步的分析来看)
2) applyBeanPostProcessorsBeforeInitialization():获取并应用所有后置处理器的postProcessBeforeInitialization()
3) invokeInitMethods();执行自定义的初始化方法
4) applyBeanPostProcessorsAfterInitialization();获取并执行所有后置处理器的postProcessAfterInitialization();
4. BeanPostProcessor(AnnotationAwareAspectJAutoProxyCreator)创建成功;
7、把BeanPostProcessor注册到BeanFactory中;
- beanFactory.addBeanPostProcessor(postProcessor);
//AbstractApplicationContext.class
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
//PostProcessorRegistrationDelegate
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
//1. 先获取ioc容器已经定义了的需要创建对象的所有BeanPostProcessor
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// Register BeanPostProcessorChecker that logs an info message when
// a bean is created during BeanPostProcessor instantiation, i.e. when
// a bean is not eligible for getting processed by all BeanPostProcessors.
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
//2. 给容器中加别的BeanPostProcessor
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
List<String> orderedPostProcessorNames = new ArrayList<String>();
List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, register the BeanPostProcessors that implement PriorityOrdered.
//3. 优先注册实现了PriorityOrdered接口的BeanPostProcessor;
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// Next, register the BeanPostProcessors that implement Ordered.
//4. 再给容器中注册实现了Ordered接口的BeanPostProcessor;
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// Now, register all regular BeanPostProcessors.
//5. 注册没实现优先级接口的BeanPostProcessor;
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// Finally, re-register all internal BeanPostProcessors.
sortPostProcessors(internalPostProcessors, beanFactory);
//6. 注册BeanPostProcessor,实际上就是创建BeanPostProcessor对象,保存在容器中
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// Re-register post-processor for detecting inner beans as ApplicationListeners,
// moving it to the end of the processor chain (for picking up proxies etc).
//7. 把BeanPostProcessor注册到BeanFactory中;
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
第一大点 + 第二大点以上部分 == 创建和注册AnnotationAwareAspectJAutoProxyCreator的过程
AnnotationAwareAspectJAutoProxyCreator是 postProcessBeforeInstantiation 类型的后置处理器
注意区分:
postProcessBeforeInstantiation — > Instantiation 实例化
postProcessBeforeInitialization — > Initialization 初始化
5.refresh()中调用finishBeanFactoryInitialization(beanFactory);完成BeanFactory初始化工作;创建剩下的单实例bean
大体流程:
AbstractApplicationContext#getBean
-> AbstractBeanFactory#getBean
-> AbstractBeanFactory#doGetBean
-> DefaultSingletonBeanRegistry#getSingleton(String, boolean)
-> DefaultSingletonBeanRegistry#getSingleton(String, ObjectFactory<?>)
-> AbstractAutowireCapableBeanFactory#createBean
-> resolveBeforeInstantiation 或 doCreateBean
(有两次getSingleton)
1、遍历获取容器中所有的Bean,依次创建对象getBean(beanName);
2、创建bean doGetBean()
-
先从缓存中获取当前bean,如果能获取到,说明bean是之前被创建过的,直接使用,否则再创建;
只要创建好的Bean都会被缓存起来
-
createBean():创建bean;
注意:
-
BeanPostProcessor是在Bean对象创建完成初始化前后调用的, 由4.6.3可知
-
InstantiationAwareBeanPostProcessor是在创建Bean实例之前先尝试用后置处理器返回对象的,由上图可知
- resolveBeforeInstantiation(beanName, mbdToUse);解析BeforeInstantiation
希望后置处理器在此能返回一个代理对象;如果能返回代理对象就使用,如果不能就继续
- doCreateBean(beanName, mbdToUse, args);真正的去创建一个bean实例;和4.6流程一样;
-
结论:
AnnotationAwareAspectJAutoProxyCreator 实现了 InstantiationAwareBeanPostProcessor 因此在所有bean创建之前会有一个拦截,会调用postProcessBeforeInstantiation(),尝试返回bean的代理对象
接下来接着分析AnnotationAwareAspectJAutoProxyCreator的具体作用,postProcessBeforeInstantiation()做了什么事情
6.AnnotationAwareAspectJAutoProxyCreator
AnnotationAwareAspectJAutoProxyCreator【InstantiationAwareBeanPostProcessor】的作用:
1、每一个bean创建之前,调用postProcessBeforeInstantiation();
关心MathCalculator(普通bean)和LogAspect(添加了@Aspcet)的创建(自定义的两个bean)
(调试 beanClass = MathCalculator 的情况 :)
-
判断当前bean是否在advisedBeans中(保存了所有需要增强bean)
-
判断当前bean是否是基础类型的(实现Advice、Pointcut、Advisor、AopInfrastructureBean接口,或者是否是切面(使用了@Aspect))
-
是否需要跳过
1) 获取候选的增强器(切面里面的通知方法)【List candidateAdvisors】
-
每一个封装的通知方法的增强器是 InstantiationModelAwarePointcutAdvisor 类型的;
-
判断每一个增强器是否是 AspectJPointcutAdvisor 类型的;返回true
2) 调用父类的shouldSkip ,永远返回false
2、创建对象 (执行new MathCalculator — bean的实例化过程(getBean、doCreateBean…))
3、对象创建完成之后调用:
postProcessAfterInitialization;
return wrapIfNecessary(bean, beanName, cacheKey); //包装如果需要的情况下
-
获取当前bean的所有增强器(通知方法) Object[] specificInterceptors
-
找到候选的所有的增强器(找哪些通知方法是需要切入当前bean方法的)
-
获取到能在bean使用的增强器。
-
给增强器排序
-
-
保存当前bean在advisedBeans中;
-
如果当前bean需要增强,创建当前bean的代理对象;
-
获取所有增强器(通知方法)
-
保存到proxyFactory
-
创建代理对象:Spring自动决定
- JdkDynamicAopProxy(config); jdk动态代理;(bean实现了接口)
- ObjenesisCglibAopProxy(config);cglib的动态代理;(没有实现接口)
-
-
给容器中返回当前组件(MathCalculator的实例)使用cglib增强了的代理对象;
-
以后容器中获取到的就是这个组件的代理对象,执行目标方法的时候,代理对象就会执行通知方法的流程;
小结:
AnnotationAwareAspectJAutoProxyCreator是一个InstantiationAwareBeanPostProcessor类型的后置处理器,它会在bean创建前后执行一些操作,特别是创建后会判断当前bean是否需要增强,若是则返回当前bean的代理对象
然后该代理对象执行方法利用拦截器链进行调用,因此接下来分析目标方法的执行过程:
7.目标方法执行
在目标方法上打上断点
容器中保存了组件的代理对象(cglib增强后的对象),这个对象里面保存了详细信息(比如增强器,目标对象,xxx);
1、CglibAopProxy.intercept();拦截目标方法的执行
2、根据ProxyFactory对象获取将要执行的目标方法拦截器链;
//CglibAopProxy.intercept();
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
-
List interceptorList保存所有拦截器 length = 5
一个默认的ExposeInvocationInterceptor 和 4个增强器;
-
遍历所有的增强器,将其转为Interceptor;
Object[] = registry.getInterceptors(advisor);
-
在advisor instanceof PointcutAdvisor的情况下:
将增强器转为List;
如果是MethodInterceptor,直接加入到集合中
如果不是,使用AdvisorAdapter将增强器转为MethodInterceptor;
转换完成返回MethodInterceptor[];
3、如果没有拦截器链,直接执行目标方法;
拦截器链(每一个通知方法又被包装为方法拦截器,利用MethodInterceptor机制)
4、如果有拦截器链,把需要执行的目标对象,目标方法,拦截器链等信息传入创建一个 CglibMethodInvocation 对象,并调用 :
Object retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
小结:
在目标方法执行之前,会把增强器转化成拦截器,形成一个拦截器链,
然后根据该拦截器链创建一个CglibMethodInvocation 并调用 proceed()
接下来开始分析proceed方法的执行,即拦截器的触发过程:
5、拦截器链的触发过程;
-
如果没有拦截器执行执行目标方法,或者 拦截器的索引 = 拦截器数组-1 (即执行到了最后一个拦截器)执行目标方法;
-
链式获取每一个拦截器,拦截器执行invoke方法,每一个拦截器等待下一个拦截器执行完成返回以后再来执行;
拦截器链的机制,保证通知方法与目标方法的执行顺序;
Ⅲ、总结
1、@EnableAspectJAutoProxy 开启AOP功能
2、@EnableAspectJAutoProxy 会给容器中注册一个组件 AnnotationAwareAspectJAutoProxyCreator
3、AnnotationAwareAspectJAutoProxyCreator是一个后置处理器;
4、容器的创建流程:
-
registerBeanPostProcessors()注册后置处理器;创建AnnotationAwareAspectJAutoProxyCreator对象
-
finishBeanFactoryInitialization()初始化剩下的单实例bean
-
创建业务逻辑组件和切面组件
-
AnnotationAwareAspectJAutoProxyCreator拦截组件的创建过程
-
组件创建完之后,判断组件是否需要增强
是:切面的通知方法,包装成增强器(Advisor);给业务逻辑组件创建一个代理对象(cglib);
5、执行目标方法:
- 代理对象执行目标方法
- CglibAopProxy.intercept();
- 得到目标方法的拦截器链(增强器包装成拦截器MethodInterceptor)
- 利用拦截器的链式机制,依次进入每一个拦截器进行执行;
- 效果:
- 正常执行:前置通知 --> 目标方法 --> 后置通知 --> 返回通知
- 出现异常:前置通知 --> 目标方法 --> 后置通知 --> 异常通知