Spring Aop面向切面編程和源碼解析之二

斷點位置:

AbstractAutoProxyCreator.setBeanFactory()

AbstractAutoProxyCreator.postProcessBeforeInstantiation() //有後置處理器的邏輯;

AbstractAdvisorAutoProxyCreator.setBeanFactory()->initBeanFactory() //第一個斷點這個位置

AnnotationAwareAspectJAutoProxyCreator.initBeanFactory()

1)、傳入配置類,創建ioc容器

public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
        this();
        register(annotatedClasses);//註冊配置類
        refresh();
}

2)、註冊配置類,調用refresh()刷新容器;

AbstractApplicationContext.refresh() //刷新

3)、註冊bean的後置處理器來方便攔截bean的創建

refresh()中的registerBeanPostProcessors(beanFactory);

// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);

3.1 註冊BeanPostProcessors後置處理器

PostProcessorRegistrationDelegate.registerBeanPostProcessors()//方法中
    
public static void registerBeanPostProcessors(
            ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
        //先獲取ioc容器已經定義了的需要創建對象的所有BeanPostProcessor(未創建只是定義了的)
        String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
    //org.springframework.aop.config.internalAutoProxyCreator  就是之前註冊的AnnotationAwareAspectJAutoProxyCreator

     
        int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
        beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

        
        List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
        List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
        List<String> orderedPostProcessorNames = new ArrayList<String>();
        List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
    // 分別分離 BeanPostProcessors 實現了 PriorityOrdered,Ordered, and the rest. 的接口
        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);
            }
        }
        
        // 優先註冊實現了PriorityOrdered接口的BeanPostProcessor;
        sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
        registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

        // 再註冊實現了Ordered接口的BeanPostProcessor;
        List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();
        for (String ppName : orderedPostProcessorNames) {
            //獲取bean ,沒有bean就創建這個bean
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            orderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }
        sortPostProcessors(orderedPostProcessors, beanFactory);
         //把BeanPostProcessor註冊到BeanFactory中beanFactory.addBeanPostProcessor(postProcessor);
        registerBeanPostProcessors(beanFactory, orderedPostProcessors);

        // 再註冊沒實現優先級接口的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);
        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));
    }

3.4 再給容器中註冊實現了Ordered接口的BeanPostProcessor;

3.5 註冊沒實現優先級接口的BeanPostProcessor;

3.6 註冊BeanPostProcessor

實際上就是創建BeanPostProcessor對象,保存在容器中;

創建internalAutoProxyCreator的BeanPostProcessor【AnnotationAwareAspectJAutoProxyCreator】

  • 1)、創建Bean的實例

    //獲取 getBean()->創建 doCreateBean()->do
    BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
    @Override
    public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
        return doGetBean(name, requiredType, null, false);
    }   
  • 2)、populateBean;給bean的各種屬性賦值 AbstractAutowireCapableBeanFactory.doCreateBean()->populateBean()

  • 3)、initializeBean:初始化bean; AbstractAutowireCapableBeanFactory.doCreateBean()-initializeBean()

    protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
       if (System.getSecurityManager() != null) {
          AccessController.doPrivileged(new PrivilegedAction<Object>() {
             @Override
             public Object run() {
                invokeAwareMethods(beanName, bean);
                return null;
             }
          }, getAccessControlContext());
       }
       else {
          // 1.處理Aware接口的方法回調  
          invokeAwareMethods(beanName, bean);
       }
    
       Object wrappedBean = bean;
       if (mbd == null || !mbd.isSynthetic()) {
          //2 .應用後置處理器的postProcessBeforeInitialization()方法,就是bean的before()
          wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
       }
    
       try {
           //3.執行自定義的初始化方法 ,執行setBeanFactory()方法
          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()) {
           //4 .應用後置處理器的postProcessAfterInitialization()方法,就是bean的After()
          wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
       }
       return wrappedBean;
    }

    • 1)、invokeAwareMethods處理Aware接口的方法回調

      //AbstractAutowireCapableBeanFactory
      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) {
               ((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
            }
             //執行 AnnotationAwareAspectJAutoProxyCreator 的setBeanFactory()方法
            if (bean instanceof BeanFactoryAware) {
               ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
            }
         }
      }
    • 2)、applyBeanPostProcessorsBeforeInitialization():執行應用後置處理器的postProcessBeforeInitialization()方法

      public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
            throws BeansException {
      
         Object result = existingBean;
         for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
            result = beanProcessor.postProcessBeforeInitialization(result, beanName);
            if (result == null) {
               return result;
            }
         }
         return result;
      }
    • 3)、invokeInitMethods();執行自定義的初始化方法

    • 4)、applyBeanPostProcessorsAfterInitialization();執行後置處理器的postProcessAfterInitialization();

  • 4)、BeanPostProcessor(AnnotationAwareAspectJAutoProxyCreator)創建成功;-->aspectJAdvisorsBuilder

3.7 把BeanPostProcessor註冊到BeanFactory中 ,註冊完成

 //beanFactory.addBeanPostProcessor(postProcessor);

registerBeanPostProcessors(beanFactory, orderedPostProcessors);

​ AnnotationAwareAspectJAutoProxyCreator => InstantiationAwareBeanPostProcessor

4)、finishBeanFactoryInitialization(beanFactory);

斷點在:AbstractAutoProxyCreator->postProcessBeforeInstantiation()方法上

AbstractApplicationContext.refresh()-->finishBeanFactoryInitialization(beanFactory); 方法中

完成BeanFactory初始化工作;創建剩下的單實例bean

createBean:


//Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
//希望後置處理器在此能返回一個代理對象;如果能返回代理對象就使用,如果不能就繼續doCreateBean(beanName, mbdToUse, args);真正的去創建一個bean實例; 
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
        Object bean = null;
        if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
            // Make sure bean class is actually resolved at this point.
            if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
                Class<?> targetType = determineTargetType(beanName, mbd);
                if (targetType != null) {
                     // 後置處理器先嚐試返回對象;
                    bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                    if (bean != null) {
                        bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
                    }
                }
            }
            mbd.beforeInstantiationResolved = (bean != null);
        }
        return bean;
}

protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
// 拿到所有後置處理器,如果是InstantiationAwareBeanPostProcessor;就執行postProcessBeforeInstantiation()這個方法
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
                // AbstractAutoProxyCreator 實現了SmartInstantiationAwareBeanPostProcessor 接口,SmartInstantiationAwareBeanPostProcessor繼承了InstantiationAwareBeanPostProcessor
                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                //此時就是調用AbstractAutoProxyCreator.postProcessBeforeInstantiation()方法
                Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
                if (result != null) {
                    return result;
                }
            }
        }
        return null;
    }

後置處理器的區別:

 AnnotationAwareAspectJAutoProxyCreator在所有bean創建之前會有一個攔截,會調用postProcessBeforeInstantiation() 
 AnnotationAwareAspectJAutoProxyCreator 會在任何bean創建之前先嚐試返回bean的實例 
【BeanPostProcessor是在Bean對象創建完成初始化前後調用的】
【InstantiationAwareBeanPostProcessor是在創建任何Bean實例之前先嚐試用後置處理器返回對象的】

5. AbstractAutoProxyCreator 後置處理器

5.1postProcessBeforeInstantiation()後置處理器功能

斷點到:AbstractAutoProxyCreator.postProcessBeforeInstantiation()中,只關心MathCalculator和LogAspect的創建,斷點到這個2個對應的beanClass

1)、每一個bean創建之前,調用postProcessBeforeInstantiation();

  • 關心MathCalculator和LogAspect的創建

    • 1)、判斷當前bean是否在advisedBeans中(保存了所有需要增強bean)2)、判斷當前bean是否是基礎類型的Advice、Pointcut、Advisor、AopInfrastructureBean, 或者是否是切面(@Aspect) 3)、是否需要跳過 1)、獲取候選的增強器(切面裏面的通知方法)【List<Advisor> candidateAdvisors】 每一個封裝的通知方法的增強器是 InstantiationModelAwarePointcutAdvisor; 判斷每一個增強器是否是 AspectJPointcutAdvisor 類型的;返回true 2)、永遠返回false


public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        Object cacheKey = getCacheKey(beanClass, beanName);

        if (beanName == null || !this.targetSourcedBeans.contains(beanName)) {
            //1)、判斷當前bean是否在advisedBeans中(保存了所有需要增強bean)
            if (this.advisedBeans.containsKey(cacheKey)) {
                return null;
            }
            //2)、isInfrastructureClass(beanClass) 判斷當前bean是否是基礎類型的Advice、Pointcut、Advisor、AopInfrastructureBean,或者是否是切面(@Aspect)
            //、shouldSkip()是否需要跳過
            if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
                this.advisedBeans.put(cacheKey, Boolean.FALSE);
                return null;
            }
        }

         
        if (beanName != null) {
            //獲取自定義的TargetSource
            TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
            if (targetSource != null) {
                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;
    }

3.1shouldSkip 說明

protected boolean shouldSkip(Class<?> beanClass, String beanName) {
        // 找到候選的增強器,就是切面裏面的通知方法
        List<Advisor> candidateAdvisors = findCandidateAdvisors();
        for (Advisor advisor : candidateAdvisors) {
 //  每一個封裝的通知方法的增強器是 InstantiationModelAwarePointcutAdvisor類型的;判斷每一個增強器是否是 AspectJPointcutAdvisor 類型的;返回true,當前放回false
            if (advisor instanceof AspectJPointcutAdvisor) {
                if (((AbstractAspectJAdvice) advisor.getAdvice()).getAspectName().equals(beanName)) {
                    return true;
                }
            }
        }
    //2)、永遠返回false
        return super.shouldSkip(beanClass, beanName);
    }

5.2 AbstractAutoProxyCreator.postProcessAfterInitialization()

postProcessBeforeInstantiation 處理完成後進入postProcessAfterInitialization()方法中

- 2)、創建對象
- postProcessAfterInitialization;
  - return wrapIfNecessary(bean, beanName, cacheKey);//包裝如果需要的情況下
    1)、獲取當前bean的所有增強器(通知方法)  Object[]  specificInterceptors
                1、找到候選的所有的增強器(找哪些通知方法是需要切入當前bean方法的)
                    //AbstractAdvisorAutoProxyCreator.findEligibleAdvisors()中
                2、獲取到能在bean使用的增強器。
                3、給增強器排序
            2)、保存當前bean在advisedBeans中;
            3)、如果當前bean需要增強,創建當前bean的代理對象;
                1)、獲取所有增強器(通知方法)
                2)、保存到proxyFactory
                3)、創建代理對象:Spring自動決定
                    JdkDynamicAopProxy(config);jdk動態代理;
                    ObjenesisCglibAopProxy(config);cglib的動態代理;
            4)、給容器中返回當前組件使用cglib增強了的代理對象;
            5)、以後容器中獲取到的就是這個組件的代理對象,執行目標方法的時候,代理對象就會執行通知方法的流程;

public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (bean != null) {
            Object cacheKey = getCacheKey(bean.getClass(), beanName);
            if (!this.earlyProxyReferences.contains(cacheKey)) {
                return wrapIfNecessary(bean, beanName, cacheKey);
            }
        }
        return bean;
}

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
        if (beanName != null && 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;
        }

        // 創建一個代理對象
        Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
        if (specificInterceptors != DO_NOT_PROXY) {
             //2)、保存當前bean在advisedBeans中;
            this.advisedBeans.put(cacheKey, Boolean.TRUE);
            //3)、如果當前bean需要增強,創建當前bean的代理對象;
            Object proxy = createProxy(
                    bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
            this.proxyTypes.put(cacheKey, proxy.getClass());
            return proxy;
        }

        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return bean;
    }

6.攔截器目標方法執行

 容器中保存了組件的代理對象(cglib增強後的對象),這個對象裏面保存了詳細信息(比如增強器,目標對象,xxx);
- 1)、CglibAopProxy.intercept();攔截目標方法的執行
  2)、根據ProxyFactory對象獲取將要執行的目標方法攔截器鏈;
            List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
            1)、List<Object> interceptorList保存所有攔截器 5個長度
                一個默認的ExposeInvocationInterceptor  4個增強器;
            2)、遍歷所有的增強器,將其轉爲Interceptor;
                registry.getInterceptors(advisor);
            3)、將增強器轉爲List<MethodInterceptor>
                                 這個DefaultAdvisorAdapterRegistry. getInterceptors()方法中處理
                    如果是MethodInterceptor,直接加入到集合中
                如果不是,使用AdvisorAdapter將增強器轉爲MethodInterceptor;
                轉換完成返回MethodInterceptor數組;
- 3)、如果沒有攔截器鏈,直接執行目標方法;
  攔截器鏈(每一個通知方法又被包裝爲方法攔截器,利用MethodInterceptor機制)
- 4)、如果有攔截器鏈,把需要執行的目標對象,目標方法,
  攔截器鏈等信息傳入創建一個 CglibMethodInvocation 對象,
            並調用 Object retVal =  mi.proceed();
- 5)、攔截器鏈的觸發過程;
  1)、如果沒有攔截器執行執行目標方法,或者攔截器的索引和攔截器數組-1大小一樣(指定到了最後一個攔截器)執行目標方法;


  if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
     return invokeJoinpoint();
  }

2)、鏈式獲取每一個攔截器,攔截器執行invoke方法,每一個攔截器等待下一個攔截器執行完成返回以後再來執行; 攔截器鏈的機制,保證通知方法與目標方法的執行順序;

 Calculate calculate=  applicationContext.getBean(Calculate.class);
 calculate.add(1,2);//斷點到這個位置,下一步

//CglibAopProxy類中
public 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) {
                 
                    oldProxy = AopContext.setCurrentProxy(proxy);
                    setProxyContext = true;
                }
                 
                target = getTarget();
                if (target != null) {
                    targetClass = target.getClass();
                }
                //根據ProxyFactory對象獲取將要執行的目標方法攔截器鏈;
                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 對象,並調用 Object retVal =  mi.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);
                }
            }
        }

 總結:

- 1)、  @EnableAspectJAutoProxy 開啓AOP功能
- 2)、 @EnableAspectJAutoProxy 會給容器中註冊一個組件 AnnotationAwareAspectJAutoProxyCreator
  3)、AnnotationAwareAspectJAutoProxyCreator是一個後置處理器;
        4)、容器的創建流程:
            1)、registerBeanPostProcessors()註冊後置處理器;創建AnnotationAwareAspectJAutoProxyCreator對象
            2)、finishBeanFactoryInitialization()初始化剩下的單實例bean
                1)、創建業務邏輯組件和切面組件
                2)、AnnotationAwareAspectJAutoProxyCreator攔截組件的創建過程
                3)、組件創建完之後,postProcessAfterInitialization判斷組件是否需要增強
                    是:切面的通知方法,包裝成增強器(Advisor);給業務邏輯組件創建一個代理對象(cglib);
        5)、執行目標方法:
            1)、代理對象執行目標方法
            2)、CglibAopProxy.intercept()
                1)、得到目標方法的攔截器鏈(增強器包裝成攔截器MethodInterceptor)
                2)、利用攔截器的鏈式機制,依次進入每一個攔截器進行執行;
                3)、效果:
                    正常執行:前置通知-》目標方法-》後置通知-》返回通知
                    出現異常:前置通知-》目標方法-》後置通知-》異常通知

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章