Spring筆記(3) - debug源碼AOP原理解析

  • 案例

    @EnableAspectJAutoProxy//開啓基於註解的aop模式
    @Configuration
    public class AOPConfig {
        //業務邏輯類加入容器中
        @Bean
        public MathCalculator mathCalculator() {
            return new MathCalculator();
        }
        //切面類加入容器中
        @Bean
        public LogAspects logAspects() {
            return new LogAspects();
        }
    }
    /**
     * AOP[動態代理]:指在程序運行期間動態的將某段代碼切入到指定方法指定位置進行運行的編程方式;
     * @Aspect 告訴Spring當前類是切面類
     */
    @Aspect
    public class LogAspects {
        /**
         * 抽取公共的切入點表達式
         * 1.本類引用:pointcut()
         * 2.引用其他切面類:全名【com.hrh.config.LogAspects.pointcut()】
         */
        @Pointcut("execution(public int com.hrh.config.MathCalculator.*(..))")
        public void pointcut() {
    
        }
        //在目標方法(div)運行之前運行
        @Before("com.hrh.config.LogAspects.pointcut()")
        public void LogStart(JoinPoint joinPoint) {
            //獲取傳入目標方法的參數對象
            Object[] args = joinPoint.getArgs();
            //Signature getSignature();獲取封裝了署名信息的對象,在該對象中可以獲取到目標方法名,所屬類的Class等信息
            System.out.println("方法名:【" + joinPoint.getSignature().getName() + "】運行@Before,參數是:" + Arrays.asList(args));
        }
        //在目標方法(div)運行之後運行
        @After("pointcut()")
        public void LogEnd(JoinPoint joinPoint) {
            System.out.println("方法名:【" + joinPoint.getSignature().getName() + "】運行@After");
        }
    
        /**
         * 獲得目標方法(div)運行的結果
         * @param joinPoint 必須是參數列表第一位,封裝了SpringAop中切面方法的信息
         * @param result    返回值
         */
        @AfterReturning(value = "pointcut()", returning = "result")
        public void LogReturn(JoinPoint joinPoint, Object result) {
            System.out.println("方法名:【" + joinPoint.getSignature().getName() + "】的返回值:" + result);
        }
        //獲得目標方法(div)運行的異常信息
        @AfterThrowing(value = "pointcut()", throwing = "e")
        public void LogException(JoinPoint joinPoint, Exception e) {
            System.out.println("方法名:【" + joinPoint.getSignature().getName() + "】的異常信息:" + e);
        }
    }
    public class MathCalculator {
        public int div(int i,int j){
            return i/j;
        }
    }
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AOPConfig.class);
        MathCalculator bean = context.getBean(MathCalculator.class);
        bean.div(1, 1);
  • 在探究下面的原理前,請帶着下面的流程總結進行學習:

    1. @EnableAspectJAutoProxy開啓AOP功能(SpringBoot會默認開啓,所以不需要該註解);

    2. @EnableAspectJAutoProxy會給容器註冊一個AnnotationAwareAspectJAutoProxyCreator,它是一個後置處理器,會在組件的創建之前進行攔截;

    3. 容器的創建流程:

      1. registerBeanPostProcessors註冊後置處理器,創建AnnotationAwareAspectJAutoProxyCreator;
      2. finishBeanFactoryInitialization初始化剩下的單實例bean;
        1. 創建業務邏輯組件和切面組件;
        2. AnnotationAwareAspectJAutoProxyCreator會攔截組件的創建過程;
        3. 組件創建完成之後,wrapIfNecessary判斷組件是否需要增強;
          • 如果是,將通知方法包裝成增強器,給目標對象即業務邏輯創建一個代理對象,代理對象有各種增強器;
    4. 執行目標方法,調用CglibAopProxy.intercept進行攔截;

      1. 得到目標方法的攔截器鏈,利用攔截器的鏈式機制進行遞歸,調用proceed()依次進入每一個攔截器進行執行各種通知方法和目標方法;
      2. 效果:
        1. 正常執行:前置通知 -> 目標方法 -> 後置通知 -> 返回通知
        2. 出現異常:前置通知 -> 目標方法 -> 後置通知 -> 異常通知
  • 原理

    1. @EnableAspectJAutoProxy註解探究,需要啓用該註解AOP纔會生效

      @Target(ElementType.TYPE)
      @Retention(RetentionPolicy.RUNTIME)
      @Documented
      //給容器導入AspectJAutoProxyRegistrar
      @Import(AspectJAutoProxyRegistrar.class)
      public @interface EnableAspectJAutoProxy {
         boolean proxyTargetClass() default false;
         boolean exposeProxy() default false;
      }
      1. AspectJAutoProxyRegistrar:AspectJ自動代理註冊器,實現了registerBeanDefinitions()自定義給容器註冊bean

        class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
           @Override
           public void registerBeanDefinitions(
                 AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
                //給容器添加AUTO_PROXY_CREATOR_BEAN_NAME=AnnotationAwareAspectJAutoProxyCreator
              AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
              ....
           }
        }
        public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
            return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
        }
        public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
            BeanDefinitionRegistry registry, @Nullable Object source) {
        //註冊AnnotationAwareAspectJAutoProxyCreator
        return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
        }
      2. registerOrEscalateApcAsRequired

        private static BeanDefinition registerOrEscalateApcAsRequired(
                Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
        
            Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
            //registry註冊中第一次是不包含AUTO_PROXY_CREATOR_BEAN_NAME=internalAutoProxyCteator,走下面註冊代碼
            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;
            }
            //創建獲得AnnotationAwareAspectJAutoProxyCreator的定義信息(該對象還沒創建),然後註冊到容器DefaultListableBeanFactory中,名字叫AUTO_PROXY_CREATOR_BEAN_NAME
            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;
        }
      3. 從上面代碼可以看出下面的流程:

        1. @EnableAspectJAutoProxy註解導入AspectJAutoProxyRegistrar類
        2. AspectJAutoProxyRegistrar類最後給容器添加AnnotationAwareAspectJAutoProxyCreator
      4. 下面是AnnotationAwareAspectJAutoProxyCreator:AspectJ自動代理創建器的類關係情況,從中可以看到該類實現了BeanPostProcessor(後置處理器)BeanFacotryAware(給該類添加BeanFactory組件)對應的方法postProcessBeforeInstantiation()、postProcessAfterInitialization()、setBeanFactory(),所以研究後置處理器在bean創建前後所做的事情自動裝配BeanFactory就可以了。

        AnnotationAwareAspectJAutoProxyCreator
            -> extends AspectJAwareAdvisorAutoProxyCreator
                -> extends AbstractAdvisorAutoProxyCreator
                    -> extends AbstractAutoProxyCreator
                        -> implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware
                           -> SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor
                             -> InstantiationAwareBeanPostProcessor extends BeanPostProcessor
    2. 開啓Debug模式探究AnnotationAwareAspectJAutoProxyCreator的創建和註冊實現流程

      1. 分別在AOPConfig的@Bean註解處、AnnotationAwareAspectJAutoProxyCreator的initBeanFactory()、AbstractAdvisorAutoProxyCreator的setBeanFactory()、AbstractAutoProxyCreator的postProcessBeforeInstantiation()和postProcessAfterInitialization()處打斷點

      2. 方法流程:

        1. 傳入配置類,創建ioc容器;
        2. 註冊配置類,調用refresh刷新容器;
        3. 註冊bean的後置處理器來攔截bean的創建;
          1. 先從容器中獲取已經定義了需要創建對象的BeanPostProcessor;
          2. 給容器添加其他的BeanPostProcessor;
          3. 優先註冊實現了PriorityOrdered接口的BeanPostProcessor;
          4. 再給容器註冊實現了Ordered接口的BeanPostProcessor;
          5. 註冊其他的BeanPostProcessor;
          6. 註冊BeanPostProcessor,實際就是創建BeanPostProcessor對象(internalAutoProxyCreator),保存在容器中;
            1. 調用beanFactory.getBean();
            2. 調用doGetBean(),第一次調用對象是null,需要創建createBean();
            3. 調用doCreateBean():createBeanInstance創建實例,populateBean()屬性賦值,initializeBean()初始化實例;
            4. initializeBean()初始化實例:
              1. invokeAwareMethods()設置factoryBean;
              2. applyBeanPostProcessorsBeforeInitialization()執行所有的postProcessBeforeInitialization方法,即AbstractAutoProxyCreator的postProcessBefforeInstantiation();
              3. invokeInitMethods()執行自定義初始化方法;
              4. applyBeanPostProcessorsAfterInitialization()執行所有的postProcessAfterInitialization方法;
            5. 創建完再次獲取對象getSingleton(),加入到bean集合中;
          7. 創建完獲取加入到容器中registerBeanPostProcessors():beanFactory.addBeanPostProcessor(postProcessor);
      3. 代碼流程:

        1)AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AOPConfig.class);
        2)AnnotationConfigApplicationContext:refresh()
        3)AbstractApplicationContext:refresh()
            @Override
            public void refresh() throws BeansException, IllegalStateException {
                synchronized (this.startupShutdownMonitor) {
                    ...
                    //註冊bean的後置處理器來攔截bean的創建
                    registerBeanPostProcessors(beanFactory);
                    ...
                    //註冊其他BeanPostProcessor
                    finishBeanFactoryInitialization(beanFactory);
                    ...
                }
            }
        4)PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
        5) public static void registerBeanPostProcessors(
                 ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
                //先從容器中獲取已經定義了需要創建對象的BeanPostProcessor,比如下面的值
                //org.springframework.context.annotation.internalAutowiredAnnotationProcessor
                //org.springframework.context.annotation.internalCommonAnnotationProcessor
                //org.springframework.aop.config.internalAutoProxyCreator【EnableAspectJAutoProxy註解已經定義了給容器添加internalAutoProxyCreator=AnnotationAwareAspectJAutoProxyCreator】
              String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
              int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
              //給容器添加其他的BeanPostProcessor
              beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
              // 分離實現了PriorityOrdered,Ordered和其他接口的BeanPostProcessor
              List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
              List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
              List<String> orderedPostProcessorNames = new ArrayList<>();
              List<String> nonOrderedPostProcessorNames = new ArrayList<>();
              for (String ppName : postProcessorNames) {
                  //實現了PriorityOrdered(有優先級排序)接口的添加到priorityOrderedPostProcessors中
                 if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                    BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
                    priorityOrderedPostProcessors.add(pp);
                    //如果是MergedBeanDefinitionPostProcessor添加到internalPostProcessors中
                    if (pp instanceof MergedBeanDefinitionPostProcessor) {
                       internalPostProcessors.add(pp);
                    }
                 }
                 else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
                    //實現了Ordered接口的添加到orderedPostProcessorNames中
                    orderedPostProcessorNames.add(ppName);
                 }
                 else {
                     //其他添加到nonOrderedPostProcessorNames中
                    nonOrderedPostProcessorNames.add(ppName);
                 }
              }
        
              //排序
              sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
              // 優先註冊實現了PriorityOrdered的BeanPostProcessor
              registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
        
              //然後註冊實現了Ordered的BeanPostProcessor
              List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
              //遍歷所有的internalAutoProxyCreator[AnnotationAwareAspectJAutoProxyCreator實現了Ordered]
              for (String ppName : orderedPostProcessorNames) {
                 //獲得BeanPostProcessor
                 BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
                 orderedPostProcessors.add(pp);
                 if (pp instanceof MergedBeanDefinitionPostProcessor) {
                    internalPostProcessors.add(pp);
                 }
              }
              sortPostProcessors(orderedPostProcessors, beanFactory);
              //註冊,加入到beanFactory中
              registerBeanPostProcessors(beanFactory, orderedPostProcessors);
        
              //註冊其他的nonOrderedPostProcessors
              List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
              for (String ppName : nonOrderedPostProcessorNames) {
                 BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
                 nonOrderedPostProcessors.add(pp);
                 if (pp instanceof MergedBeanDefinitionPostProcessor) {
                    internalPostProcessors.add(pp);
                 }
              }
              registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
        
              // 最後註冊internalPostProcessors
              sortPostProcessors(internalPostProcessors, beanFactory);
              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).
              beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
           }
           
            //註冊
            private static void registerBeanPostProcessors(
                    ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
                //遍歷加入到beanFactory中
                for (BeanPostProcessor postProcessor : postProcessors) {
                    beanFactory.addBeanPostProcessor(postProcessor);
                }
            }
        6)beanFactory.getBean:
            public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
              return doGetBean(name, requiredType, null, false);
            }
        7)protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
                 @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
                 ....
                // 創建bean實例
                if (mbd.isSingleton()) {
                   //第一次獲取是null,需要創建實例
                   sharedInstance = getSingleton(beanName, () -> {
                      try {
                         return createBean(beanName, mbd, args);//創建實例
                      }
                      ...
                   });
                   bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                }
              ....
           }
        8)public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
                ....
                try {
                   //獲得對象,第一次是null,走createBean方法創建實例,創建完後重新過來獲取
                   singletonObject = singletonFactory.getObject();
                   newSingleton = true;
                }
                ....
                if (newSingleton) {
                   addSingleton(beanName, singletonObject);//添加到bean集合中
                }
                ....
          }
        9) protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
                 throws BeanCreationException {
              ....
              try {
                 //創建實例org.springframework.aop.config.internalAutoProxyCreator
                 Object beanInstance = doCreateBean(beanName, mbdToUse, args);
                 if (logger.isTraceEnabled()) {
                    logger.trace("Finished creating instance of bean '" + beanName + "'");
                 }
                 return beanInstance;
              }
              ....
           }
        
        10)protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
                     throws BeanCreationException {
        
                  // 定義實例
                  BeanWrapper instanceWrapper = null;
                  if (mbd.isSingleton()) {
                     instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
                  }
                  if (instanceWrapper == null) {
                     instanceWrapper = createBeanInstance(beanName, mbd, args);//創建實例internalAutoProxyCreator
                  }
                  //獲得bean實例internalAutoProxyCreator
                  final Object bean = instanceWrapper.getWrappedInstance();
                  ....
                  // 初始化bean實例
                  Object exposedObject = bean;
                  try {
                     //對bean進行屬性賦值
                     populateBean(beanName, mbd, instanceWrapper);
                     //初始化實例org.springframework.aop.config.internalAutoProxyCreator
                     exposedObject = initializeBean(beanName, exposedObject, mbd);
                  }
                  ....
               }
        11)protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
              ....
              else {
                 //設置beanFactory
                 invokeAwareMethods(beanName, bean);
              }
        
              Object wrappedBean = bean;
              if (mbd == null || !mbd.isSynthetic()) {
                 //執行所有的postProcessBeforeInitialization方法,即AbstractAutoProxyCreator的postProcessBefforeInstantiation()
                 wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
              }
        
              try {
                 invokeInitMethods(beanName, wrappedBean, mbd);//執行初始化方法
              }
              catch (Throwable ex) {
                 throw new BeanCreationException(
                       (mbd != null ? mbd.getResourceDescription() : null),
                       beanName, "Invocation of init method failed", ex);
              }
              if (mbd == null || !mbd.isSynthetic()) {
                 //執行所有的postProcessAfterInitialization方法
                 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
              }
        
              return wrappedBean;
           }
        12)private void invokeAwareMethods(final String beanName, final Object bean) {
              if (bean instanceof Aware) {
                 if (bean instanceof BeanNameAware) {
                    ((BeanNameAware) bean).setBeanName(beanName);
                 }
                 if (bean instanceof BeanClassLoaderAware) {
                    ClassLoader bcl = getBeanClassLoader();
                    if (bcl != null) {
                       ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
                    }
                 }
                 //設置beanFactory,後面調用AbstractAdvisorAutoProxyCreator的setBeanFactory(),給AbstractAdvisorAutoProxyCreator添加BeanFactory並且初始化BeanFactory
                 if (bean instanceof BeanFactoryAware) {
                    ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
                 }
              }
            }
    3. 在第3步registerBeanPostProcessors完成AnnotationAwareAspectJAutoProxyCreator的註冊後(作爲一個後置處理器,接下來探討它的執行時機),執行finishBeanFactoryInitialization註冊其他的Bean,比如internalAutowiredAnnotationProcessor等

      1.  方法流程:從下面第4步可以看出在創建任何bean之前會進行攔截,獲取AnnotationAwareAspectJAutoProxyCreator的postProcessBeforeInstantiation進行執行

        1. finishBeanFactoryInitialization註冊其他的bean
        2. preInstantiateSingletons遍歷容器中所有bean名字,創建對象getBean()
        3. getBen() -> doGetBean() -> getSingleton()獲取單實例 -> createBean()
          1. doGetBean會從緩存中查找,如果能獲取,說明已經被創建過,直接獲取,不行再getSingleton()獲取單實例 -> createBean()
        4. create()創建實例前調用resolveBeforeInstantiation進行解析BeforeInstantiation,希望後置處理器能返回一個代理對象,如果能獲取返回該bean(AnnotationAwareAspectJAutoProxyCreator)
        5. 如果第4步解析不能返回bean,調用doCreateBean進行創建
      2. 代碼流程:

        1protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
                ...
                /*bean:
                 *   org.springframework.context.annotation.internalConfigurationAnnotationProcessor
                 *   org.springframework.context.annotation.internalAutowiredAnnotationProcessor
                 *   org.springframework.context.annotation.internalCommonAnnotationProcessor
                 *   org.springframework.context.event.internalEventListenerProcessor
                 *   org.springframework.context.event.internalEventListenerFactory
                 *   AOPConfig、mathCalculator、logAspects
                 *   org.springframework.aop.config.internalAutoProxyCreator
                 */
                 ....
                //實例化其他單實例(上面的bean)
                beanFactory.preInstantiateSingletons();
            }
        2public void preInstantiateSingletons() throws BeansException {
                ....
                //獲取所有默認的其他bean,即上面註釋的bean
                List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
                // 遍歷容器中所有定義的bean名字
                for (String beanName : beanNames) {
                    RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
                    if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                        //是工廠bean
                        if (isFactoryBean(beanName)) {
                            Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
                            if (bean instanceof FactoryBean) {
                                final FactoryBean<?> factory = (FactoryBean<?>) bean;
                                boolean isEagerInit;
                                if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                                    isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
                                                    ((SmartFactoryBean<?>) factory)::isEagerInit,
                                            getAccessControlContext());
                                }
                                else {
                                    isEagerInit = (factory instanceof SmartFactoryBean &&
                                            ((SmartFactoryBean<?>) factory).isEagerInit());
                                }
                                if (isEagerInit) {
                                    getBean(beanName);
                                }
                            }
                        }
                        else {//不是工廠bean
                            getBean(beanName);//獲取bean,比如internalEventListenerProcessor
                        }
                    }
                }
            
                for (String beanName : beanNames) {
                    Object singletonInstance = getSingleton(beanName);
                    if (singletonInstance instanceof SmartInitializingSingleton) {
                        final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
                        if (System.getSecurityManager() != null) {
                            AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                                smartSingleton.afterSingletonsInstantiated();
                                return null;
                            }, getAccessControlContext());
                        }
                        else {
                            smartSingleton.afterSingletonsInstantiated();
                        }
                    }
                }
            }
        3public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
                  return doGetBean(name, requiredType, null, false);
            }
            protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
                    @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
                 ....
                //第一次獲取,提前檢查單實例緩存中是否已經注入了當前bean(bean只要被創建過,就會被緩存起來)【保證bean只會被創建一次,單實例】
                Object sharedInstance = getSingleton(beanName);
                ....
                //不在緩存中,進行創建bean
                else {
                    ....
                        // 創建bean實例
                        if (mbd.isSingleton()) {
                            //第二次獲取,進行創建bean
                            sharedInstance = getSingleton(beanName, () -> {
                                try {
                                    return createBean(beanName, mbd, args);
                                }
                                ....
                            });
                            bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);//得到bean實例
                        }
                }
                ....
            }
        4protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
                        throws BeanCreationException {
                ....
                try {
                    /**
                     *解析BeforeInstantiation,希望後置處理器能返回一個代理對象,如果能獲取返回該bean
                     *從下面的applyBeanPostProcessorsBeforeInstantiation可以看出,在下面創建每個bean之前會嘗試獲取AnnotationAwareAspectJAutoProxyCreator的實例
                     */
                    Object bean = resolveBeforeInstantiation(beanName, mbdToUse);//4.1
                    if (bean != null) {
                        return bean;
                    }
                }
                ....
                try {
                    //如果不能,創建對象
                    Object beanInstance = doCreateBean(beanName, mbdToUse, args);//4.2
                    if (logger.isTraceEnabled()) {
                        logger.trace("Finished creating instance of bean '" + beanName + "'");
                    }
                    return beanInstance;
                }
                ....
            }
        4.1protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
                Object bean = null;
                //是否已經提前被解析過
                if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
                    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
                        Class<?> targetType = determineTargetType(beanName, mbd);
                        if (targetType != null) {
                            //執行before
                            bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                            if (bean != null) {
                                //再執行after
                                bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
                            }
                        }
                    }
                    mbd.beforeInstantiationResolved = (bean != null);
                }
                return bean;
            }
            AbstractAutowireCapableBeanFactory:
            protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
                //遍歷所有的後置處理器
                for (BeanPostProcessor bp : getBeanPostProcessors()) {
                    /**
                      *如果是InstantiationAwareBeanPostProcessor執行postProcessBeforeInstantiation
                      *從上面1.4類關係圖可以看出AnnotationAwareAspectJAutoProxyCreator->InstantiationAwareBeanPostProcessor,是在創建bean實例之前先嚐試用後置處理器返回對象
                      *     1.resolveBeforeInstantiation(beanName, mbdToUse)
                      *     2.doCreateBean(beanName, mbdToUse, args)
                      *而BeanPostProcessor在bean對象創建完成初始化方法前後調用的(可查看initializeBean方法調用情況)
                      */
                    if (bp instanceof InstantiationAwareBeanPostProcessor) {
                        //如果獲取到AnnotationAwareAspectJAutoProxyCreator
                        InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                        //執行AnnotationAwareAspectJAutoProxyCreator的postProcessBeforeInstantiation
                        Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
                        if (result != null) {
                            return result;
                        }
                    }
                }
                return null;
            }
        4.2protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
                     throws BeanCreationException {
            
                  // 定義實例
                  BeanWrapper instanceWrapper = null;
                  if (mbd.isSingleton()) {
                     instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
                  }
                  if (instanceWrapper == null) {
                     instanceWrapper = createBeanInstance(beanName, mbd, args);//創建實例internalAutoProxyCreator
                  }
                  //獲得bean實例internalEventListenerProcessor
                  final Object bean = instanceWrapper.getWrappedInstance();
                  ....
                  // 初始化bean實例
                  Object exposedObject = bean;
                  try {
                     //對bean進行屬性賦值
                     populateBean(beanName, mbd, instanceWrapper);
                     //初始化實例internalEventListenerProcessor
                     exposedObject = initializeBean(beanName, exposedObject, mbd);
                  }
                  ....
            }
            protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
                  ....
                  else {
                     //設置beanFactory
                     invokeAwareMethods(beanName, bean);
                  }
            
                  Object wrappedBean = bean;
                  if (mbd == null || !mbd.isSynthetic()) {
                     //執行所有的postProcessBeforeInitialization方法,即AbstractAutoProxyCreator的postProcessBefforeInstantiation()
                     wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
                  }
            
                  try {
                     invokeInitMethods(beanName, wrappedBean, mbd);//對bean執行初始化方法
                  }
                  catch (Throwable ex) {
                     throw new BeanCreationException(
                           (mbd != null ? mbd.getResourceDescription() : null),
                           beanName, "Invocation of init method failed", ex);
                  }
                  if (mbd == null || !mbd.isSynthetic()) {
                     //執行所有的postProcessAfterInitialization方法
                     wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
                  }
            
                  return wrappedBean;
            }
    4. 從上面的代碼流程可以看到在創建每個bean之前都會調用AnnotationAwareAspectJAutoProxyCreator的postProcessBeforeInstantiation,在上面的案例代碼中對AOPConfig的@Bean創建加入容器打下斷點,debug探究它的執行流程

      1. 方法流程

        1. 判斷當前bean是否在advisedBeans中(保存了所有需要增強的bean,即需要切面增強的bean,比如案例代碼中的MathCalculator);
        2. 判斷當前類是否是基礎類型(Advice、Pointcut、Advisor、AopInfrastructureBean、Aspect切面)和是否需要跳過不處理;
          1. 對於是否跳過內部的處理邏輯是:獲取LogAspects的所有增強方法,比如LogStart、LogEnd等,判斷每個增強器是否是AspectJPointctuAdvisor,如果是返回true,否則返回false;
        3. 在處理完上面的邏輯後,進行bean的創建比如MathCalculator的創建,執行到案例代碼中@Bean的new對象創建;
      2. 代碼流程:

            //解析比如MathCalculator類、Aspect註解的類
        1public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
                //beanClass:class com.hrh.config.MathCalculator
                //beanName:mathCalculator
                Object cacheKey = getCacheKey(beanClass, beanName);
        
                if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
                    //判斷當前類是否是增強類
                    if (this.advisedBeans.containsKey(cacheKey)) {
                        return null;
                    }
                    //判斷當前類是否是基礎類型(Advice、Pointcut、Advisor、AopInfrastructureBean、Aspect切面),是否需要跳過不處理
                    if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
                        this.advisedBeans.put(cacheKey, Boolean.FALSE);//存放基礎類logAspects、AOPConfig
                        return null;
                    }
                }
                //獲得自定義TargetSource,直接返回null
                TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
                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;
                }
        
                return null;
            }
            AbstractAutoProxyCreator:
        2protected boolean isInfrastructureClass(Class<?> beanClass) {
                //基礎類型Advice、Pointcut、Advisor、AopInfrastructureBean
                boolean retVal = Advice.class.isAssignableFrom(beanClass) ||
                        Pointcut.class.isAssignableFrom(beanClass) ||
                        Advisor.class.isAssignableFrom(beanClass) ||
                        AopInfrastructureBean.class.isAssignableFrom(beanClass);
                if (retVal && logger.isTraceEnabled()) {
                    logger.trace("Did not attempt to auto-proxy infrastructure class [" + beanClass.getName() + "]");
                }
                return retVal;
            }
            AnnotationAwareAspectJAutoProxyCreator:
            protected boolean isInfrastructureClass(Class<?> beanClass) {
                //還會判斷是否是基礎類型和Aspect切面
                return (super.isInfrastructureClass(beanClass) ||
                        (this.aspectJAdvisorFactory != null && this.aspectJAdvisorFactory.isAspect(beanClass)));
            }
            //找到是否有切面註解
            public boolean isAspect(Class<?> clazz) {
                return (hasAspectAnnotation(clazz) && !compiledByAjc(clazz));
            }
            private boolean hasAspectAnnotation(Class<?> clazz) {
                return (AnnotationUtils.findAnnotation(clazz, Aspect.class) != null);
            }
            AspectJAwareAdvisorAutoProxyCreator:
        3protected boolean shouldSkip(Class<?> beanClass, String beanName) {
                //獲得所有的通知方法,比如LogAspects的LogStart、LogEnd等
                //通知方法封裝的對象candidateAdvisors是InstantiationModelAwarePointcutAdvisor:
                //     expression [com.hrh.config.LogAspects.pointcut()]; advice method [public void com.hrh.config.LogAspects.LogStart(org.aspectj.lang.JoinPoint)];
                //判斷每個增強器(通知方法)是否是AspectJPointcutAdvisor
                List<Advisor> candidateAdvisors = findCandidateAdvisors();
                for (Advisor advisor : candidateAdvisors) {
                    if (advisor instanceof AspectJPointcutAdvisor &&
                            ((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
                        return true;
                    }
                }
                return super.shouldSkip(beanClass, beanName);//直接返回false
    5.   從上面的代碼第3步的4.1中的resolveBeforeInstantiation可以看出在before後進行bean的創建,後會執行applyBeanPostProcessorsAfterInitialization,debug探究它的執行流程

      1. 方法流程:

        1.  如果需要包裝調用wrapIfNecessary,即對當前bean比如MathCalculator的方法進行增強方法;
        2. 獲取bean的所有增強器(通知方法)getAdvicesAndAdvisorsForBean;
          1. findCandidateAdvisors拿到候選的增強器,比如LogAspects的LogStart、LogEnd等4個;
          2. findAdvisorsThatCanApply找到可以應用到beanClass的增強器,即找到哪些通知方法是可以切入到當前bean方法的;
          3. canApply使用切入點表達式來匹配當前bean的哪些方法使用增強器;
          4. 給增強器排序;
        3. bean已經增強過了,放到緩存advisedBean中;
        4. createProxy創建代理對象;
          1. 拿到所有增強器buildAdvisors;
          2. 放入代理工廠中;
          3. 得到代理對象,如果沒有,創建代理對象;
          4. 創建代理對象:(如果當前bean實現了接口)JdkDynamicAopProxy創建jdk代理,否則ObjenesisCglibAopProxy創建CGlib代理;
        5. 給容器返回當前bean經過jdk或CGlib動態代理增強了的對象mathCalculator,即當前bean的每個方法都得到了符合的切面的通知方法,那麼以後執行mathCalculator的方法,就會執行獲取到的這個代理對象,就會調用增強方法;
      2. 代碼流程:

        1public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
                    throws BeansException {
        
                Object result = existingBean;
                for (BeanPostProcessor processor : getBeanPostProcessors()) {
                    //得到通知方法增強了的MathCalculator對象
                    Object current = processor.postProcessAfterInitialization(result, beanName);
                    if (current == null) {
                        return result;
                    }
                    result = current;
                }
                return result;
            }
            //給容器返回當前bean經過jdk或CGlib動態代理增強了的對象
        2public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
                if (bean != null) {
                    //bean:MathCalculator,beanName:mathCalculator
                    Object cacheKey = getCacheKey(bean.getClass(), beanName);
                    if (this.earlyProxyReferences.remove(cacheKey) != bean) {
                        return wrapIfNecessary(bean, beanName, cacheKey);//如果需要則進行包裝
                    }
                }
                return bean;
            }
        3protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
                if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
                    return bean;
                }
                if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
                    return bean;
                }
                 //判斷當前類是否是基礎類型,是否需要跳過不處理
                if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
                    this.advisedBeans.put(cacheKey, Boolean.FALSE);
                    return bean;
                }
        
                //獲取bean的所有增強器(通知方法)
                Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);//3.1
                if (specificInterceptors != DO_NOT_PROXY) {
                    //當前bean已經增強過了,放到緩存advisedBean中
                    this.advisedBeans.put(cacheKey, Boolean.TRUE);
                    //創建代理對象
                    Object proxy = createProxy(
                            bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));//3.2
                    this.proxyTypes.put(cacheKey, proxy.getClass());
                    return proxy;
                }
        
                this.advisedBeans.put(cacheKey, Boolean.FALSE);
                return bean;
            }
               //AbstractAdvisorAutoProxyCreator:
        3.1protected Object[] getAdvicesAndAdvisorsForBean(
                        Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
                    //找到可用的增強器
                    List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
                    if (advisors.isEmpty()) {
                        return DO_NOT_PROXY;//返回null
                    }
                    return advisors.toArray();
                }
        3.1.2protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
                    //拿到候選的增強器,比如LogAspects的LogStart、LogEnd等4個
                    List<Advisor> candidateAdvisors = findCandidateAdvisors();
                    //找到可以應用到beanClass的增強器,即找到哪些通知方法是可以切入到當前bean方法的
                    List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
                    extendAdvisors(eligibleAdvisors);
                    if (!eligibleAdvisors.isEmpty()) {
                        //對增強器進行排序,即方法調用增強器是有順序的,先LogStart後LogEnd
                        eligibleAdvisors = sortAdvisors(eligibleAdvisors);
                    }
                    return eligibleAdvisors;
                }
        3.1.3protected List<Advisor> findAdvisorsThatCanApply(
                        List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
        
                    ProxyCreationContext.setCurrentProxiedBeanName(beanName);
                    try {
                        //用AOP工具找到能用的增強器
                        return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
                    }
                    finally {
                        ProxyCreationContext.setCurrentProxiedBeanName(null);
                    }
                }
        3.1.4public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
                    if (candidateAdvisors.isEmpty()) {
                        return candidateAdvisors;
                    }
                    List<Advisor> eligibleAdvisors = new ArrayList<>();
                    for (Advisor candidate : candidateAdvisors) {
                        if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
                            eligibleAdvisors.add(candidate);
                        }
                    }
                    boolean hasIntroductions = !eligibleAdvisors.isEmpty();
                    for (Advisor candidate : candidateAdvisors) {
                        if (candidate instanceof IntroductionAdvisor) {
                            // already processed
                            continue;
                        }
                        //判斷是否能用,如果可以加入到eligibleAdvisors
                        if (canApply(candidate, clazz, hasIntroductions)) {
                            eligibleAdvisors.add(candidate);
                        }
                    }
                    return eligibleAdvisors;
                }
                //下面是使用切入點表達式來匹配當前bean的哪些方法使用增強器
        3.1.5public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
                    if (advisor instanceof IntroductionAdvisor) {
                        return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
                    }
                    else if (advisor instanceof PointcutAdvisor) {
                        PointcutAdvisor pca = (PointcutAdvisor) advisor;
                        return canApply(pca.getPointcut(), targetClass, hasIntroductions);
                    }
                    else {
                        // It doesn't have a pointcut so we assume it applies.
                        return true;
                    }
                }
              //創建代理對象
        3.2protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
                    @Nullable Object[] specificInterceptors, TargetSource targetSource) {
        
                if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
                    AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
                }
                //創建代理對象創建工廠
                ProxyFactory proxyFactory = new ProxyFactory();
                proxyFactory.copyFrom(this);
        
                if (!proxyFactory.isProxyTargetClass()) {
                    if (shouldProxyTargetClass(beanClass, beanName)) {
                        proxyFactory.setProxyTargetClass(true);
                    }
                    else {
                        evaluateProxyInterfaces(beanClass, proxyFactory);
                    }
                }
                //拿到所有增強器
                Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
                //把增強器保存到代理工廠中
                proxyFactory.addAdvisors(advisors);
                proxyFactory.setTargetSource(targetSource);
                customizeProxyFactory(proxyFactory);
        
                proxyFactory.setFrozen(this.freezeProxy);
                if (advisorsPreFiltered()) {
                    proxyFactory.setPreFiltered(true);
                }
                //得到代理對象
                return proxyFactory.getProxy(getProxyClassLoader());
            }
                //得到代理對象
        3.2.1public Object getProxy(@Nullable ClassLoader classLoader) {
                     return createAopProxy().getProxy(classLoader);
                }
                //創建代理對象
                protected final synchronized AopProxy createAopProxy() {
                    if (!this.active) {
                        activate();
                    }
                    return getAopProxyFactory().createAopProxy(this);
                }
                //DefaultAopProxyFactory:
        3.2.2public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
                    if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
                        Class<?> targetClass = config.getTargetClass();
                        if (targetClass == null) {
                            throw new AopConfigException("TargetSource cannot determine target class: " +
                                    "Either an interface or a target is required for proxy creation.");
                        }
                        //如果bean實現了接口使用jdk動態代理
                        if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
                            return new JdkDynamicAopProxy(config);//創建jdk代理
                        }
                        return new ObjenesisCglibAopProxy(config);//創建CGlib代理
                    }
                    else {
                        return new JdkDynamicAopProxy(config);
                    }
                }
    6.  上面分析了對每個bean根據切入表達式進行了增強方法的封裝,創建了一個代理對象,那麼接下來來分析MathCalculator.div()的執行路徑,在main方法中對bean.div()打斷點進行debug分析

      1. 方法流程:

        1. 容器中保存了增強後的代理對象,從下圖可以看出MathCalculator對象是經過cglib代理過的,這個對象保存了很多信息,比如增強器advisors保存了增強方法、保存了目標對象targetSource等等;
        2. 調用CglibAopProxy.intercept攔截目標方法執行;

          1. 調用getInterceptorsAndDynamicInterceptionAdvice將每一個增強器即通知方法包裝爲攔截器;
            1. 獲取緩存鍵,根據鍵值對獲取值;
            2. 緩存如果沒有,getInterceptorsAndDynamicInterceptionAdvice進行獲取攔截鏈放入到緩存中;
              1. List<Object> interceptorList集合保存所有攔截器,長度是所有的增強器的數量,默認+4個增強器;
              2. 遍歷所有增強器,Interceptor[] interceptors = registry.getInterceptors(advisor)將增強器封裝到interceptors,然後加入到interceptorList集合中,最後返回interceptorList集合;
                1. 將advisor轉換成interceptors;
                2. advice【異常通知AspectJAfterThrowingAdvice、後置通知AspectJAfterAdvice】如果是MethodInterceptor,直接加進去interceptors;
                3. 使用適配器【MethodBeforeAdviceAdapter、AfterReturningAdviceAdapter、ThrowsAdviceAdapter】遍歷,使用增強器適配器將advice【前置通知AspectJMethodBeforeAdvice和後置返回通知AspectAfterReturningAdvice】轉換爲MethodInterceptor;
          2. 如果沒有攔截器鏈,直接執行目標方法;
          3. 如果有,把目標對象、目標方法、攔截器鏈等參數傳遞給CglibMethodInvocation進行包裝,然後調用proceed();
      2. 代碼流程:

            //CglibAopProxy.intercept:攔截目標方法執行
        1public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
                Object oldProxy = null;
                boolean setProxyContext = false;
                Class<?> targetClass = null;
                Object target = null;
                try {
                    if (this.advised.exposeProxy) {
                        // Make invocation available if necessary.
                        oldProxy = AopContext.setCurrentProxy(proxy);
                        setProxyContext = true;
                    }
                    //目標對象:MathCalculator
                    target = getTarget();
                    if (target != null) {
                        targetClass = target.getClass();
                    }
                    //根據ProxyFactory獲取將要執行的目標方法的攔截器鏈【將每一個增強器即通知方法包裝爲攔截器】
                    //method:div()
                    List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
                    Object retVal;
                    //如果沒有攔截器鏈,直接執行目標方法
                    if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
                        Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
                        retVal = methodProxy.invoke(target, argsToUse);
                    }
                    else {//如果有,把目標對象、目標方法、攔截器鏈等參數傳遞給CglibMethodInvocation,然後調用proceed
                        retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
                    }
                    retVal = processReturnType(proxy, target, method, retVal);
                    return retVal;
                }
                finally {
                    if (target != null) {
                        releaseTarget(target);
                    }
                    if (setProxyContext) {
                        // Restore old proxy.
                        AopContext.setCurrentProxy(oldProxy);
                    }
                }
            }
        2public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, Class<?> targetClass) {
                //獲取緩存鍵
                MethodCacheKey cacheKey = new MethodCacheKey(method);
                //根據鍵值對獲取值
                List<Object> cached = this.methodCache.get(cacheKey);
                //緩存如果沒有,進行獲取攔截鏈放入到緩存中
                if (cached == null) {
                    cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
                            this, method, targetClass);
                    this.methodCache.put(cacheKey, cached);
                }
                return cached;
            }
        3public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
                    Advised config, Method method, Class<?> targetClass) {
        
                // This is somewhat tricky... We have to process introductions first,
                // but we need to preserve order in the ultimate list.
                //保存所有攔截器,長度是所有的增強器的數量,默認+4個增強器
                List<Object> interceptorList = new ArrayList<Object>(config.getAdvisors().length);
                Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
                boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);
                AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
                //遍歷所有增強器,將增強器封裝到interceptors,然後加入到interceptorList中
                for (Advisor advisor : config.getAdvisors()) {
                    if (advisor instanceof PointcutAdvisor) {
                        // Add it conditionally.
                        PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
                        if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
                            MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
                            MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
                            if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) {
                                if (mm.isRuntime()) {
                                    // Creating a new object instance in the getInterceptors() method
                                    // isn't a problem as we normally cache created chains.
                                    for (MethodInterceptor interceptor : interceptors) {
                                        interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
                                    }
                                }
                                else {
                                    interceptorList.addAll(Arrays.asList(interceptors));
                                }
                            }
                        }
                    }
                    else if (advisor instanceof IntroductionAdvisor) {
                        IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
                        if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
                            Interceptor[] interceptors = registry.getInterceptors(advisor);
                            interceptorList.addAll(Arrays.asList(interceptors));
                        }
                    }
                    else {
                        Interceptor[] interceptors = registry.getInterceptors(advisor);
                        interceptorList.addAll(Arrays.asList(interceptors));
                    }
                }
        
                return interceptorList;
            }
        4public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
                //將advisor轉換成interceptors
                List<MethodInterceptor> interceptors = new ArrayList<MethodInterceptor>(3);
                Advice advice = advisor.getAdvice();
                //advice【異常通知AspectJAfterThrowingAdvice、後置通知AspectJAfterAdvice】如果是MethodInterceptor,直接加進去interceptors
                if (advice instanceof MethodInterceptor) {
                    interceptors.add((MethodInterceptor) advice);
                }
                //使用適配器遍歷,使用增強器適配器將advice【前置通知AspectJMethodBeforeAdvice和後置返回通知AspectAfterReturningAdvice】轉換爲MethodInterceptor
                //適配器:MethodBeforeAdviceAdapter、AfterReturningAdviceAdapter、ThrowsAdviceAdapter
                for (AdvisorAdapter adapter : this.adapters) {
                    if (adapter.supportsAdvice(advice)) {
                        interceptors.add(adapter.getInterceptor(advisor));
                    }
                }
                if (interceptors.isEmpty()) {
                    throw new UnknownAdviceTypeException(advisor.getAdvice());
                }
                //轉換完成,返回數組
                return interceptors.toArray(new MethodInterceptor[interceptors.size()]);
            } 
    7.  上面講了會將所有的通知方法轉換爲攔截器鏈,然後包裝到CglibMethodInvocation中,然後調用proceed()執行,下面探究proceed的執行流程即攔截器鏈的觸發過程

      1.  方法流程:

        1. 包裝後的攔截器鏈:
        2. proceed方法每次執行,currentInterceptorIndex會自增+1,根據這個currentInterceptorIndex索引從攔截器鏈chain中取出攔截器;
        3. 如果沒有攔截器了直接執行目標方法invokeJoinpoint(),比如MathCalculator.div(),如果有攔截器,先根據currentInterceptorIndex從攔截器鏈取出攔截器,調用MethodInterceptor.invoke執行各種通知方法
        4. 攔截器的執行是遞歸的順序,在捕獲到異常時,會直接執行異常通知而跳過返回通知:
      2. 代碼流程:

            //DefaultAdvisorAdapterRegistry:每次執行proceed,currentInterceptorIndex會自增1,根據索引從攔截器鏈中取出攔截器
        1public Object proceed() throws Throwable {
                //    We start with an index of -1 and increment early.
                //currentInterceptorIndex記錄當前攔截器索引,從-1開始,判斷當前currentInterceptorIndex是否等於攔截器鏈的長度-1(5-1=4),如果攔截器鏈爲空,則判斷成立
                //沒有攔截器直接執行目標方法,或者攔截器的索引和攔截器數組-1大小一樣(執行到了最後一個攔截器)執行目標方法
                if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
                    return invokeJoinpoint();//反射直接執行目標方法
                }
                //currentInterceptorIndex+1,從攔截器鏈中獲取索引爲0的攔截器ExposeInvocationInterceptor
                Object interceptorOrInterceptionAdvice =
                        this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
                if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
                    // Evaluate dynamic method matcher here: static part will already have
                    // been evaluated and found to match.
                    InterceptorAndDynamicMethodMatcher dm =
                            (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
                    if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
                        return dm.interceptor.invoke(this);
                    }
                    else {
                        // Dynamic matching failed.
                        // Skip this interceptor and invoke the next in the chain.
                        return proceed();
                    }
                }
                else {
                    //調用MethodInterceptor.invoke(),執行各種通知方法
                    return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
                }
            }
        2protected Object invokeJoinpoint() throws Throwable {
                return AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments);
            }
        3public static Object invokeJoinpointUsingReflection(Object target, Method method, Object[] args)
                    throws Throwable {
        
                // Use reflection to invoke the method.
                try {
                    ReflectionUtils.makeAccessible(method);
                    return method.invoke(target, args);//反射直接執行目標方法
                }
                catch (InvocationTargetException ex) {
                    // Invoked method threw a checked exception.
                    // We must rethrow it. The client won't see the interceptor.
                    throw ex.getTargetException();
                }
                catch (IllegalArgumentException ex) {
                    throw new AopInvocationException("AOP configuration seems to be invalid: tried calling method [" +
                            method + "] on target [" + target + "]", ex);
                }
                catch (IllegalAccessException ex) {
                    throw new AopInvocationException("Could not access method [" + method + "]", ex);
                }
            }
            //MethodInvocation放到線程共享中ThreadLocal
        4private static final ThreadLocal<MethodInvocation> invocation = new NamedThreadLocal<MethodInvocation>("Current AOP method invocation");
            //ExposeInvocationInterceptor
            public Object invoke(MethodInvocation mi) throws Throwable {
                //從線程共享變量ThreadLocal拿出一個MethodInvocation
                MethodInvocation oldInvocation = invocation.get();
                invocation.set(mi);//將MethodInvocation放入ThreadLocal中
                try {
                    return mi.proceed();//執行DefaultAdvisorAdapterRegistry的proceed
                }
                finally {
                    invocation.set(oldInvocation);
                }
            }
            //AspectJAfterThrowingAdvice
            public Object invoke(MethodInvocation mi) throws Throwable {
                try {
                    return mi.proceed();
                }
                catch (Throwable ex) {//拿到拋出的異常
                    if (shouldInvokeOnThrowing(ex)) {
                        invokeAdviceMethod(getJoinPointMatch(), null, ex);//執行異常通知
                    }
                    throw ex;
                }
            }
            //AfterReturningAdviceInterceptor
            public Object invoke(MethodInvocation mi) throws Throwable {
                Object retVal = mi.proceed();//proceed如果沒有問題,執行下面代碼,如果有問題,下面通知跳過執行AspectJAfterThrowingAdvice.invoke拋出異常
                this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());//執行返回通知
                return retVal;
            }
            //AspectJAfterAdvice
            public Object invoke(MethodInvocation mi) throws Throwable {
                try {
                    return mi.proceed();
                }
                finally {
                    invokeAdviceMethod(getJoinPointMatch(), null, null);//執行後置通知
                }
            }
            //MethodBeforeAdviceInterceptor
            public Object invoke(MethodInvocation mi) throws Throwable {
                //調用之前先輸出before前置通知
                this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() );
                return mi.proceed();
            }
    發表評論
    所有評論
    還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
    相關文章