AopAutoConfiguration流程


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()")标注的方法


     

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值