1. 程式人生 > >Spring系列之Spring框架和SpringAOP整合過程分析(十二)

Spring系列之Spring框架和SpringAOP整合過程分析(十二)

轉載請註明出處:https://blog.csdn.net/zknxx/article/details/80808447
在這篇文章中我們接著上一篇的文章說。在上一篇文章中我們提到了getAdvicesAndAdvisorsForBean這個方法,這個方法的內容是為目標物件挑選合適的Advisor類,其原始碼如下:

    //targetSource 為null
    protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) {
        List
<Advisor> advisors = findEligibleAdvisors(beanClass, beanName); //如果獲取的Advisor為空的話,則直接返回DO_NOT_PROXY 返回這個值的時候 是不建立代理物件 if (advisors.isEmpty()) { return DO_NOT_PROXY; } return advisors.toArray(); } protected List<Advisor> findEligibleAdvisors(Class
<?> beanClass, String beanName) {
//這個方法我們在上一章中分析過了 獲取Spring容器中的所有的通知方法 封裝為Advisor集合 List<Advisor> candidateAdvisors = findCandidateAdvisors(); //這一步就是為目標物件挑選合適的Advisor 即目標物件和切點表示式相匹配 //此處的分析 請參考這裡:https://blog.csdn.net/zknxx/article/details/79735405 List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName); //這個方法做的事是向 上一步獲取到的Advisor中 插入ExposeInvocationInterceptor.ADVISOR 插在第一個位置
extendAdvisors(eligibleAdvisors); if (!eligibleAdvisors.isEmpty()) { //排序 很複雜的實現 不說了 如果你對一個目標物件使用多個 相同型別的通知的話 請把這些通知放到不同的Aspect中,並實現Order介面或者使用Ordered註解標註順序 eligibleAdvisors = sortAdvisors(eligibleAdvisors); } return eligibleAdvisors; }

最後我們再看看目標物件的建立過程:

    //specificInterceptors 上面的方法中獲取到的Advisor 
    //targetSource 為 new SingletonTargetSource(bean) 
    //將Spring容器中創建出來的bean封裝為了SingletonTargetSource
    protected Object createProxy(
            Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
        //這裡將目標Bean的Class設定為BeanDefinition中的一個屬性 
        //在使用JDK動態代理的時候 可能會用到這個屬性  https://stackoverflow.com/questions/45463757/what-is-interface-based-proxying
        if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
            AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
        }
        //這裡建立了一個新的 ProxyFactory
        ProxyFactory proxyFactory = new ProxyFactory();
        //copy原類的配置 重寫賦值的動作   單例變多例
        proxyFactory.copyFrom(this);
        //這裡是 判斷是否強制使用 cglib
        if (!proxyFactory.isProxyTargetClass()) {
            //這裡 判斷是 使用jdk動態代理 還是cglib代理
            if (shouldProxyTargetClass(beanClass, beanName)) {
                proxyFactory.setProxyTargetClass(true);
            }
            else {
                evaluateProxyInterfaces(beanClass, proxyFactory);
            }
        }
        //這裡又重寫構建了一次 Advisor  看看是否 設定了通用的攔截
        //這裡講所有的Advisor和配置的通用攔截都轉換為了Advisor型別
        Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
        for (Advisor advisor : advisors) {
            proxyFactory.addAdvisor(advisor);
        }
        //targetSource 裡是包含目標物件的
        proxyFactory.setTargetSource(targetSource);
        customizeProxyFactory(proxyFactory);

        proxyFactory.setFrozen(this.freezeProxy);
        if (advisorsPreFiltered()) {
            proxyFactory.setPreFiltered(true);
        }
        //建立代理物件 關於建立代理物件的分析 請參考:https://blog.csdn.net/zknxx/article/details/79764107
        return proxyFactory.getProxy(getProxyClassLoader());
    }