ProxyProcessorSupport
AbstractAutoProxyCreator
AbstractAdvisorAutoProxyCreator
AspectJAwareAdvisorAutoProxyCreator
AnnotationAwareAspectJAutoProxyCreator
起点:
-> SpringApplication.run()
-> SpringApplication.refreshContext()
-> SpringApplication.refresh()
-> AbstractApplicationContext.refresh()
### 第一阶段:开启aop, AopAutoConfiguration流程或@EnableAspectJAutoProxy
-> AbstractApplicationContext.invokeBeanFactoryPostProcessors()
...
-> ConfigrationClassPostProcesor.postProcessBeanDefinitionRegistry()
-> ConfigrationClassPostProcesor.processConfigBeanDefinitions()
ConfigurationClassParser.parse() 调用包扫描,详细....
this.reader.loadBeanDefinitions(configClasses) 处理解析到的bean定义
-> ConfigrationClassBeanDefinitionReader.loadBeanDefinitions(Set<ConfigurationClass> configurationModel) configurationModel是解析到的主类所在包所有bean定义
for (ConfigurationClass configClass : configurationModel) { 开始遍历
loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator)
}
-> ConfigrationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass()
if (trackedConditionEvaluator.shouldSkip(configClass)) {
return; 如果要跳过,就返回
}
if (configClass.isImported()) { 处理Import
registerBeanDefinitionForImportedConfigurationClass(configClass);
}
for (BeanMethod beanMethod : configClass.getBeanMethods()) { 处理类中的@Bean
loadBeanDefinitionsForBeanMethod(beanMethod);
}
loadBeanDefinitionsFromImportedResources(configClass.getImportedResources()) 处理类中的ImportResource
loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars()) 处理Register
-> ConfigrationClassBeanDefinitionReader.loadBeanDefinitionsFromRegistrars(registers) 此时的registrars参数是AopAutoConfiguration$AspectJAutoProxyingConfiguration
此时就触发@EnableAspectJAutoProxy(proxyTargetClass = false)或@EnableAspectJAutoProxy(proxyTargetClass = true)注解
即:SpringBoot的AOP是默认开启的(添加注解检测spirng.aop.auto是否有值并检测到Advice类就会进行自动配置不需
要加注解@EnableAspectJAutoProxy),默认使用cglib代理。
如要开启jdk代理,需要修改配置 spring.aop.proxy-target-class=false
-> ImportBeanDefinitionRegistrar.registerBeanDefinitions()
-> AspectJAutoProxyRegistrar.registerBeanDefinitions()
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry) 把AnnotationAwareAspectJAutoProxyCreator对应的bean定义放到ioc容器中
总结:Spirng boot使用@EnableAspectJAutoProxy开启aop或使用AopAutoConfiguration也会调用@EnableAspectJAutoProxy开启aop,都会
执行AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(),
只是触发的ConfigurationClass不同:com.yfw.learn.Application或AopAutoConfiguration$AspectJAutoProxyingConfiguration$CglibAutoProxyConfiguration
同时存在会创建两次
## 处理实现了Order接口的BeanPostProcessor类型的后置处理器
-> AbstractApplicationContext.registerBeanPostProcessors()
-> PostProcessorRegistrationDelegate.registerBeanPostProcessors()
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class) pp是org.springframework.aop.config.internalAutoProxyCreator
...
-> AbstractAutowireCapableBeanFactory.doCreateBean()
-> AbstractAutowireCapableBeanFactory.initializeBean()
-> AbstractAutowireCapableBeanFactory.invokeAwareMethods()
...
-> AnnotationAwareAspectJAutoProxyCreator.initBeanFactory()
this.aspectJAdvisorsBuilder =
new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory)
### 第二阶段: 解析切面
-> AbstractApplicationContext.onRefresh()
-> ServletWebServerApplication.getWebServerFactory()
this.getBeanFactory().getBean(beanNames[0], ServletWebServerFactory.class) 触发getBean()创建tomcatServletWebServerFactory
....
-> AbstractAutowireCapableBeanFactory.createBean()
beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse) 重点
-> AbstractAutoProxyCreator.postProcessBeforeInstantiation() 重点 解析切面 创建代理
1、Object cacheKey = getCacheKey(beanClass, beanName)
2、if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) { 解析切面
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
3、TargetSource targetSource = getCustomTargetSource(beanClass, beanName)
4、if (targetSource != null) { 创建代理
if (StringUtils.hasLength(beanName)) {
this.targetSourcedBeans.add(beanName);
}
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
## 解析切面步骤
-> AspectJAwareAdvisorAutoProxyCreator.shouldSkip()
List<Advisor> candidateAdvisors = findCandidateAdvisors()
-> AnnotationAwareAspectJAutoProxyCreator.findCandidateAdvisors()
List<Advisor> advisors = super.findCandidateAdvisors();
// Build Advisors for all AspectJ aspects in the bean factory.
if (this.aspectJAdvisorsBuilder != null) {
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
-> AbstractAdvisorAutoProxyCreator.findCandidateAdvisors()
-> BeanFactoryAdvisorRetrievalHelper.findAdvisorBeans()
advisors.add(this.beanFactory.getBean(name, Advisor.class))
没找到,退栈并执行buildAspectJAdvisors
-> BeanFactoryAspectJAdvisorsBuilder.buildAspectJAdvisors() 遍历所有bean定义,找到标注@Aspect注解的bean定义
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors()
在后置postProcessAfterInitialization方法中对每个bean匹配,是否创建代理
-> AbstractAutoProxyCreator.postProcessAfterInitialization()
-> AbstractAutoProxyCreator.wrapIfNecessary()
-> AbstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean()
-> AbstractAdvisorAutoProxyCreator.findEligibleAdvisors()
-> AbstractAdvisorAutoProxyCreator.findCandidateAdvisors()
-> AbstractAdvisorAutoProxyCreator.findAdvisorsThatCanApply()
sortAdvisors()
-> AbstractAutoProxyCreator.createProxy() 匹配到了就创建代理
-> AbstractAutoProxyCreator.buildAdvisors()
-> ProxyFactory.getProxy()
createAopProxy().getProxy(classLoader) 创建代理
总结: 由于在onRefrsh()会创建bean,在AnnotationAwareAspectJAutoProxyCreator的postProcessBeforeInstantiation方法中解析切面中的注解(如@Aspect、@Before等)
并把不能匹配的bean缓存起来
-> AbstractApplicationContext.finishBeanFactoryInitialization()
...
-> AbstractAutoProxyCreator.postProcessAfterInitialization() 对所有bean判断,是否可以创建代理
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
-> AbstractAutoProxyCreator.createProxy()
-> AbstractAutoProxyCreator.buildProxy()
ProxyFactory proxyFactory = new ProxyFactory()
-> ProxyFactory.getProxy()
createAopProxy().getProxy(classLoader)
-> CglibAopProxy.getProxy()
总结:创建动态代理:在bean初始化方法invokeInitMethod前调用注册的beanPostProcessor.postProcessAfterInitialization拿到之前缓存的advisor判断当前表达式是否被切点表达式命中,
匹配就为bean创建动态代理wrapIfNecessary
### 第三阶段:拦截反射的invoke方法
spring boot 调用时
1、通过反射执行method.invoke方法,不论时jdk代理还是cglib代理,都会调用到spirng aop的MethodInterceptor执行增强
如cglib的
-> CglibAopProxy$DynamicAdvisedInterceptor.intercept()
TargetSource targetSource = this.advised.getTargetSource()
target = targetSource.getTarget()
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass) 获取拦截链
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed()
-> ReflectiveMethodInvocation.proceed()
((MethodInterceptor) interceptorOrInterceptionAdvice).invoke()
-> ExposeInvocationInterceptor.invoke()
mi.proceed() mi是ReflectiveMethodInvocation: public java.lang.String com.yfw.learn.TestController.test(); target is of class [com.yfw.learn.TestController]
-> MethodBeforeAdviceInterceptor.invoke()
-> AspectJMethodBeforeAdvice.invoke()
invokeAdviceMethod(getJoinPointMatch(), null, null);
-> AbstractAspectJAdvice.invokeAdviceMethod()
invokeAdviceMethodWithGivenArgs(argBinding(getJoinPoint(), jpMatch, returnValue, ex))
-> AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs()
this.aspectJAdviceMethod.invoke(this.aspectInstanceFactory.getAspectInstance(), actualArgs)
-> 执行切面中@Before("pointCut()")标注的方法
执行完退栈,执行invokeJoinpoint()
-> ReflectiveMethodInvocation.invokeJoinpoint()
-> 执行被拦截的方法
执行完退栈,执行invokeJoinpoint()
-> ReflectiveMethodInvocation.invokeJoinpoint()
-> 执行切面中@After("pointCut()")标注的方法