@EnableAspectJAutoProxy Aop功能开启注解
为容器中导入 @Import(AspectJAutoProxyRegistrar.class)组件,在其重写方法中为 ioc容器 注册 AnnotationAwareAspectJAutoProxyCreator (Aspectj自动代理生成器)保存beandefinition;
明名为 "org.springframework.aop.config.internalAutoProxyCreator";(起名)
AnnotationAwareAspectJAutoProxyCreator initBeanFactory();
->AspectJAwareAdvisorAutoProxyCreator
->AbstractAdvisorAutoProxyCreator ----》 setBeanFactory();
->AbstractAutoProxyCreator implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware( 后置处理器 ,在bean,beanfactory初始化完成后做事情)
---->postProcessBeforeInstantiation();
流程
1.创建ioc容器,传入主配置类
2.注册配置类,调用Refresh()方法。
3.registerBeanPostProcessors(beanFactory);注册bean的后置处理器,来拦截bean的创建。
a:先获取ioc容器已经定义的需要创建对象的所有BeanPostProcessor(例如@EnableAspectJAutoProxy注解导入的 AnnotationAwareAspectJAutoProxyCreator );
b:给容器中加入别的BeanPostProcessor
c:优先注册实现PriorityOrder接口的BeanPostProcessor,下来是实现Order接口的,最后是没实现优先级接口的。
d:创建bean实例internalAutoProxyCreator ==== AnnotationAwareAspectJAutoProxyCreator
e:初始化bean包括 invokeAwareMethods() ---》 applyBeanPostProcessorsBeforeInitialization(应用后置处理器) ---》invokeInitMethods(执行类初始化方法(init))
---》 applyBeanPostProcessorsAfterInitialization
执行aware方法
4:完成剩余单实例bean的初始化 getBean -》 doGetBean -》
a:先从缓存中获取,如果可以获取到,说明之前被创建过。只要创建好的bean 都会被缓存起来
b:createBean -》AbstractAutowireCapableBeanFactory.resolveBeforeInstantiation() // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
希望后置处理器在此能返回一个代理对象
1. 后置处理器先尝试返回对象
AnnotationAwareAspectJAutoProxyCreator 会在所有bean创建之前尝试创建代理对象
2.判断当前对象是否在advisedBeans中(保存了是否需要增强的bean)
Advice.class.isAssignableFrom(beanClass) ||
Pointcut.class.isAssignableFrom(beanClass) ||
Advisor.class.isAssignableFrom(beanClass) ||
AopInfrastructureBean.class.isAssignableFrom(beanClass) 和 shouldSkip(beanClass, beanName) 拿到候选的 增强器 findCandidateAdvisors()
after:
3.如果当前bean需要增强,则创建bean的代理对象
保存增强器到代理工厂,再创建代理对象。
通过jdk(基于接口式的代理)或cglib(通过继承父类)创建代理。下来容器中获取到的就是该对象的代理对象。
c:doCreateBean 完成真正的创建对象逻辑
AOP执行机制
1.以cglib为例 ,执行被代理方法时,代码会进入CglibAopProxy.intercept 方法
2.先获取将要执行方法的拦截器链。
3.创建一个CglibMethodInvocation对象,然后调用proceed方法。返回结果。