1. 程式人生 > >8-spring原始碼3.2.18解讀+spring技術內幕(IOC容器的依賴注入(反射+遞迴呼叫))

8-spring原始碼3.2.18解讀+spring技術內幕(IOC容器的依賴注入(反射+遞迴呼叫))

1、導讀

以上對IOC容器的初始化過程做了詳細的分析,這個初始化過程完成的主要工作是在IOC容器中建立BeanDefinition資料對映。再次過程中並沒有對Bean依賴關係進行注入,接下來將分析一下IOC容器是怎麼樣對Bean的依賴關係進行注入的。

假設當前IOC容器已經載入了使用者定義的Bean資訊,開始分析依賴注入的原理。首先,注意到依賴注入的過程是使用者第一次向IOC容器索要Bean時觸發的,當然也有例外,也就是我們可以在BeanDefinition資訊中通過控制lazy-init屬性來讓容器完成對Bean的預例項化。這個預例項化實際上也是一個完成依賴注入的過程,但它在初始化的過程中完成的。當用戶想

IOC容器索要Bean時,如BeanFactory中,有一個getBean介面的定義,這個介面的實現就是觸發依賴注入發生的地方,下面我們將從DefaultListableBeanFactory的基類AbstractBeanFactory入手getBean的實現。

2、AbstractBeanFactory

//這裡是對BeanFactory介面的實現,比如getBean介面方法

//這些getBean介面方法最終是通過呼叫doGetBean來實現的

public Object getBean(String name) throws BeansException {
    return this.doGetBean(name, (Class)null, (Object[])null, false);
}

public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
    return this.doGetBean(name, requiredType, (Object[])null, false);
}

public Object getBean(String name, Object... args) throws BeansException {
    return this.doGetBean(name, (Class)null, args, false);
}

public <T> T getBean(String name, Class<T> requiredType, Object... args) throws BeansException {
    return this.doGetBean(name, requiredType, args, false);
}

//這裡是實際取得Bean的地方,也是觸發依賴注入的地方
protected <T> T doGetBean(String name, Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException {
    final String beanName = this.transformedBeanName(name);
   //先從快取中取得Bean,處理那些已經被建立過的單例模式的Bean,對這種Bean的請求不需要重複的建立,直接返回即可

Object sharedInstance = this.getSingleton(beanName);
    Object bean;
    if(sharedInstance != null && args == null) {
        if(this.logger.isDebugEnabled()) {
            if(this.isSingletonCurrentlyInCreation(beanName)) {
                this.logger.debug("Returning eagerly cached instance of singleton bean \'" + beanName + "\' that is not fully initialized yet - a consequence of a circular reference");
            } else {
                this.logger.debug("Returning cached instance of singleton bean \'" + beanName + "\'");
            }
        }

   //這裡的getObjectForBeanInstance完成的是FactoryBean的相關處理,以取得FactoryBean的生產結果。
        bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
    } else {
        if(this.isPrototypeCurrentlyInCreation(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName);
        }

    //這裡對IOC容器中的BeanDefinition是否存在進行檢查,檢查是否能在當前BeanFactory中取得需要的Bean,如果在當前的工廠中取不到,則到雙親BeanFactory中去取,如果雙親工廠取不到,那就順著雙親BeanFactory鏈一直往上查詢
        BeanFactory ex = this.getParentBeanFactory();
        if(ex != null && !this.containsBeanDefinition(beanName)) {
            String var24 = this.originalBeanName(name);
            if(args != null) {
                return ex.getBean(var24, args);
            }

            return ex.getBean(var24, requiredType);
        }

        if(!typeCheckOnly) {
            this.markBeanAsCreated(beanName);
        }

        try {

       //這裡根據Bean的名字取得BeanDefinition
            final RootBeanDefinition ex1 = this.getMergedLocalBeanDefinition(beanName);
            this.checkMergedBeanDefinition(ex1, beanName, args);

       //獲取當前Bean的所有依賴Bean,這樣會觸發getBean的遞迴呼叫,直到取到一個沒有任何的依賴Bean為止
            String[] dependsOn = ex1.getDependsOn();
            String[] scopeName;
            if(dependsOn != null) {
                scopeName = dependsOn;
                int scope = dependsOn.length;

                for(int ex2 = 0; ex2 < scope; ++ex2) {
                    String dependsOnBean = scopeName[ex2];
                    this.getBean(dependsOnBean);
                    this.registerDependentBean(dependsOnBean, beanName);
                }
            }
//這裡通過呼叫createBean方法建立Singleton bean的例項,這裡有一個回撥函式getObject,會在getSingleton中呼叫ObjectFactorycreateBean
            if(ex1.isSingleton()) {
                sharedInstance = this.getSingleton(beanName, new ObjectFactory() {
                    public Object getObject() throws BeansException {
                        try {
                            return AbstractBeanFactory.this.createBean(beanName, ex1, args);
                        } catch (BeansException var2) {
                            AbstractBeanFactory.this.destroySingleton(beanName);
                            throw var2;
                        }
                    }
                });
                bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, ex1);
            } else if(ex1.isPrototype()) {//這裡是建立prototype bean的地方
                scopeName = null;

                Object var25;
                try {
                    this.beforePrototypeCreation(beanName);
                    var25 = this.createBean(beanName, ex1, args);
                } finally {
                    this.afterPrototypeCreation(beanName);
                }

                bean = this.getObjectForBeanInstance(var25, name, beanName, ex1);
            } else {
                String var26 = ex1.getScope();
                Scope var27 = (Scope)this.scopes.get(var26);
                if(var27 == null) {
                    throw new IllegalStateException("No Scope registered for scope \'" + var26 + "\'");
                }

                try {
                    Object var28 = var27.get(beanName, new ObjectFactory() {
                        public Object getObject() throws BeansException {
                            AbstractBeanFactory.this.beforePrototypeCreation(beanName);

                            Object var1;
                            try {
                                var1 = AbstractBeanFactory.this.createBean(beanName, ex1, args);
                            } finally {
                                AbstractBeanFactory.this.afterPrototypeCreation(beanName);
                            }

                            return var1;
                        }
                    });
                    bean = this.getObjectForBeanInstance(var28, name, beanName, ex1);
                } catch (IllegalStateException var21) {
                    throw new BeanCreationException(beanName, "Scope \'" + var26 + "\' is not active for the current thread; " + "consider defining a scoped proxy for this bean if you intend to refer to it from a singleton", var21);
                }
            }
        } catch (BeansException var23) {
            this.cleanupAfterBeanCreationFailure(beanName);
            throw var23;
        }
    }
   //這裡包含了對Bean型別檢查,如果沒有問題,則返回這個新建立的bean,這個bean已經包含了依賴關係的bean
    if(requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
        try {
            return this.getTypeConverter().convertIfNecessary(bean, requiredType);
        } catch (TypeMismatchException var22) {
            if(this.logger.isDebugEnabled()) {
                this.logger.debug("Failed to convert bean \'" + name + "\' to required type [" + ClassUtils.getQualifiedName(requiredType) + "]", var22);
            }

            throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
        }
    } else {
        return bean;
    }
}