1. 程式人生 > >騰訊分分彩源碼帶龍虎和玩法自言自語Spring依賴註入(XML配置)

騰訊分分彩源碼帶龍虎和玩法自言自語Spring依賴註入(XML配置)

類屬性 aslist when sid one != spi 匿名 sam

至於基於XML依賴註入的過程,首先要找一個比較合適的入口,那就是getBean。那麽具體是怎麽實現的呢?首先寫個測試方法:

ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("application-common.xml","application-beans.xml","application_jdbc.xml");
Object obj = app.getBean("member");
第一句在我上篇文章---Spring-BeanFactory基本工作流程中就用到了,主要是作為一個初始化IOC容器的入口,那麽我們現在的場景是:IOC容器已經創建好,我們在XML文件中配置的信息已經加載到BeanDefinition中了,那麽我們現在的目的就是去獲得它。第二句就是我們本篇文章的入口:getBean。

@Override
public Object getBean(String name) throws BeansException {
assertBeanFactoryActive();
return getBeanFactory().getBean(name);
}
首先執行的是assertBeanFactoryActive方法,本人在上一篇分析Spring源碼的時候就已經贊譽過Spring方法的命名,我們可以通過這個名字來判斷它到底有什麽意思,首先說明它是一個斷言方法,然後判斷的事BeanFactory是不是Active的,如果不是就直接拋異常了。

復制代碼
protected void assertBeanFactoryActive() {

if (!this.active.get()) {
if (this.closed.get()) {
throw new IllegalStateException(getDisplayName() + " has been closed already");
}
else {
throw new IllegalStateException(getDisplayName() + " has not been refreshed yet");
}
}
}
復制代碼
然後我們接著看getBean方法,可以看到,它會調getBeanFactory方法,他返回的是一個BeanFactory,然後調BeanFactory中的getBean方法:

在之前的文章中提到過,Spring中做實事的方法都是以do開頭的,我們可以看到,在getBean方法中調用了一個doGetBean方法,看名字可以了解到是真正拿到Bean的方法,在doGetBean方法中,首先先將我們傳進來的指定的名字轉化為管理Bean的名字,然後再創建一個名為bean的Object對象,作為我們要返回的實例。由於我們依賴註入的對象為單例,所以我們要做的就是首先在cache中檢查有沒有已經創建好的實例騰訊分分彩源碼帶龍虎和玩法(www.1159880099.com) QQ1159880099 。(Spring中從BeanDefinition創建的Bean不是存放在IOC中,而是存放在Cache容器中,IOC只是存放Bean關系),如果有Bean存在,就直接返回,如果Cache中沒有這個Bean,那麽就要創建它。

在我們要自己創建Bean的時候,首先先檢查這個Bean有沒有相關的BeanDefinition,首先要解析出Bean的原始名稱,然後現在當前BeanFactory裏檢查,如果沒有,就去父BeanFactory裏面找,如果還是找不到則沿著容器的繼承體系向父級容器查找。當當前容器的父親容器存在而且在當前容器中找不到這個bean時,就開始在父容器裏找,會找父級BeanFactory的getBean方法。

如果在當前的Bean裏面有,則首先向容器中標記這個Bean已經被創建了,然後根據指定Bean名稱獲取其父級的Bean定義,主要解決Bean繼承時子類合並父類公共屬性問題。接著獲取該Bean所有依賴Bean的名稱,如果有依賴Bean存在,那麽就遞歸獲取依賴Bean,並將依賴Bean註冊給當前的Bean。

針對於Bean的類型(單例還是原型),Spring在創建Bean的過程都不一樣,先看如果創建單例Bean的方法,首先看一下Spring在這是怎麽處理的,它先使用一個內部匿名類,就是一個SingletonFactory類,然後將Bean實際名、Bean的BeanDefinition和Bean參數傳入createBean方法(在下面會分析細節分析這個方法,這邊只是大致過一下doGetBean方法)。並返回創建出的Bean實例。同樣的,如果是一個原型Bean,因為每次都會建立一個新的實例,然後將獲得的實例返回給之前創建的bean。如果Bean既不是單例,也不是原型的話,那麽就要根據Bean定義資源中配置的生命周期範圍來選擇合適的實例化Bean方法(這種情況出現在web那塊比較多,如session,reques等)。

最後要對創建好的Bean進行檢查,如果符合規範,就認為創建好了並且返回。

復制代碼//AbstractBeanFactory.class
//獲取IOC容器中指定名稱的Bean
@Override
br/>//AbstractBeanFactory.class
//獲取IOC容器中指定名稱的Bean
@Override
//doGetBean才是真正向IoC容器獲取被管理Bean的過程
return doGetBean(name, null, null, false);
}
復制代碼
復制代碼
1
2 //真正實現向IOC容器獲取Bean的功能,也是觸發依賴註入功能的地方
3 protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
4 @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
5
6 //根據指定的名稱獲取被管理Bean的名稱,剝離指定名稱中對容器的相關依賴
7 //如果指定的是別名,將別名轉換為規範的Bean名稱
8 final String beanName = transformedBeanName(name);
9 Object bean;
10
11 // Eagerly check singleton cache for manually registered singletons.
12 //先從緩存中取是否已經有被創建過的單態類型的Bean
13 //對於單例模式的Bean整個IOC容器中只創建一次,不需要重復創建
14 Object sharedInstance = getSingleton(beanName);
15 //IOC容器創建單例模式Bean實例對象
16 if (sharedInstance != null && args == null) {
17 if (logger.isDebugEnabled()) {
18 //如果指定名稱的Bean在容器中已有單例模式的Bean被創建
19 //直接返回已經創建的Bean
20 if (isSingletonCurrentlyInCreation(beanName)) {
21 logger.debug("Returning eagerly cached instance of singleton bean ‘" + beanName +
22 "‘ that is not fully initialized yet - a consequence of a circular reference");
23 }
24 else {
25 logger.debug("Returning cached instance of singleton bean ‘" + beanName + "‘");
26 }
27 }
28 //獲取給定Bean的實例對象,主要是完成FactoryBean的相關處理
29 //註意:BeanFactory是管理容器中Bean的工廠,而FactoryBean是
30 //創建創建對象的工廠Bean,兩者之間有區別
31 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
32 }
33
34 else {
35 // Fail if we‘re already creating this bean instance:
36 // We‘re assumably within a circular reference.
37 //緩存沒有正在創建的單例模式Bean
38 //緩存中已經有已經創建的原型模式Bean
39 //但是由於循環引用的問題導致實例化對象失敗
40 if (isPrototypeCurrentlyInCreation(beanName)) {
41 throw new BeanCurrentlyInCreationException(beanName);
42 }
43
44 // Check if bean definition exists in this factory.
45 //對IOC容器中是否存在指定名稱的BeanDefinition進行檢查,首先檢查是否
46 //能在當前的BeanFactory中獲取的所需要的Bean,如果不能則委托當前容器
47 //的父級容器去查找,如果還是找不到則沿著容器的繼承體系向父級容器查找
48 BeanFactory parentBeanFactory = getParentBeanFactory();
49 //當前容器的父級容器存在,且當前容器中不存在指定名稱的Bean
50 if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
51 // Not found -> check parent.
52 //解析指定Bean名稱的原始名稱
53 String nameToLookup = originalBeanName(name);
54 if (parentBeanFactory instanceof AbstractBeanFactory) {
55 return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
56 nameToLookup, requiredType, args, typeCheckOnly);
57 }
58 else if (args != null) {
59 // Delegation to parent with explicit args.
60 //委派父級容器根據指定名稱和顯式的參數查找
61 return (T) parentBeanFactory.getBean(nameToLookup, args);
62 }
63 else {
64 // No args -> delegate to standard getBean method.
65 //委派父級容器根據指定名稱和類型查找
66 return parentBeanFactory.getBean(nameToLookup, requiredType);
67 }
68 }
69
70 //創建的Bean是否需要進行類型驗證,一般不需要
71 if (!typeCheckOnly) {
72 //向容器標記指定的Bean已經被創建
73 markBeanAsCreated(beanName);
74 }
75
76 try {
77 //根據指定Bean名稱獲取其父級的Bean定義
78 //主要解決Bean繼承時子類合並父類公共屬性問題
79 final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
80 checkMergedBeanDefinition(mbd, beanName, args);
81
82 // Guarantee initialization of beans that the current bean depends on.
83 //獲取當前Bean所有依賴Bean的名稱
84 String[] dependsOn = mbd.getDependsOn();
85 //如果當前Bean有依賴Bean
86 if (dependsOn != null) {
87 for (String dep : dependsOn) {
88 if (isDependent(beanName, dep)) {
89 throw new BeanCreationException(mbd.getResourceDescription(), beanName,
90 "Circular depends-on relationship between ‘" + beanName + "‘ and ‘" + dep + "‘");
91 }
92 //遞歸調用getBean方法,獲取當前Bean的依賴Bean
93 registerDependentBean(dep, beanName);
94 //把被依賴Bean註冊給當前依賴的Bean
95 getBean(dep);
96 }
97 }
98
99 // Create bean instance.
100 //創建單例模式Bean的實例對象
101 if (mbd.isSingleton()) {
102 //這裏使用了一個匿名內部類,創建Bean實例對象,並且註冊給所依賴的對象
103 sharedInstance = getSingleton(beanName, () -> {
104 try {
105 //創建一個指定Bean實例對象,如果有父級繼承,則合並子類和父類的定義
106 return createBean(beanName, mbd, args);
107 }
108 catch (BeansException ex) {
109 // Explicitly remove instance from singleton cache: It might have been put there
110 // eagerly by the creation process, to allow for circular reference resolution.
111 // Also remove any beans that received a temporary reference to the bean.
112 //顯式地從容器單例模式Bean緩存中清除實例對象
113 destroySingleton(beanName);
114 throw ex;
115 }
116 });
117 //獲取給定Bean的實例對象
118 bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
119 }
120
121 //IOC容器創建原型模式Bean實例對象
122 else if (mbd.isPrototype()) {
123 // It‘s a prototype -> create a new instance.
124 //原型模式(Prototype)是每次都會創建一個新的對象
125 Object prototypeInstance = null;
126 try {
127 //回調beforePrototypeCreation方法,默認的功能是註冊當前創建的原型對象
128 beforePrototypeCreation(beanName);
129 //創建指定Bean對象實例
130 prototypeInstance = createBean(beanName, mbd, args);
131 }
132 finally {
133 //回調afterPrototypeCreation方法,默認的功能告訴IOC容器指定Bean的原型對象不再創建
134 afterPrototypeCreation(beanName);
135 }
136 //獲取給定Bean的實例對象
137 bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
138 }
139
140 //要創建的Bean既不是單例模式,也不是原型模式,則根據Bean定義資源中
141 //配置的生命周期範圍,選擇實例化Bean的合適方法,這種在Web應用程序中
142 //比較常用,如:request、session、application等生命周期
143 else {
144 String scopeName = mbd.getScope();
145 final Scope scope = this.scopes.get(scopeName);
146 //Bean定義資源中沒有配置生命周期範圍,則Bean定義不合法
147 if (scope == null) {
148 throw new IllegalStateException("No Scope registered for scope name ‘" + scopeName + "‘");
149 }
150 try {
151 //這裏又使用了一個匿名內部類,獲取一個指定生命周期範圍的實例
152 Object scopedInstance = scope.get(beanName, () -> {
153 beforePrototypeCreation(beanName);
154 try {
155 return createBean(beanName, mbd, args);
156 }
157 finally {
158 afterPrototypeCreation(beanName);
159 }
160 });
161 //獲取給定Bean的實例對象
162 bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
163 }
164 catch (IllegalStateException ex) {
165 throw new BeanCreationException(beanName,
166 "Scope ‘" + scopeName + "‘ is not active for the current thread; consider " +
167 "defining a scoped proxy for this bean if you intend to refer to it from a singleton",
168 ex);
169 }
170 }
171 }
172 catch (BeansException ex) {
173 cleanupAfterBeanCreationFailure(beanName);
174 throw ex;
175 }
176 }
177
178 // Check if required type matches the type of the actual bean instance.
179 //對創建的Bean實例對象進行類型檢查
180 if (requiredType != null && !requiredType.isInstance(bean)) {
181 try {
182 T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
183 if (convertedBean == null) {
184 throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
185 }
186 return convertedBean;
187 }
188 catch (TypeMismatchException ex) {
189 if (logger.isDebugEnabled()) {
190 logger.debug("Failed to convert bean ‘" + name + "‘ to required type ‘" +
191 ClassUtils.getQualifiedName(requiredType) + "‘", ex);
192 }
193 throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
194 }
195 }
196 return (T) bean;
197 }
復制代碼
上面比較詳細的介紹了Bean實例是如何創建的,那麽接下來主要是重點分析一下幾個比較重要的方法的細節。先說一下如果Cache容器中有之前已經創建過的該Bean的實例,在31行,我們進入getObjectForBeanInstance方法。

我們已經拿到了在Cache中拿到了該Bean的FactoryBean,在這說一下FactoryBean和BeanFactory的區別,FactoryBean是用來創建生產Bean的工廠的Bean(有點繞)而BeanFactory是管理Bean的工廠。然後進入getObjectForBeanInstance方法,首先我們會去判斷這個Bean是不是一個工廠Bean,如果不是工廠Bean,或者說我們想要得到的就是一個工廠,那麽就直接返回它。如果是工廠Bean並且我們要得到的是一個Bean實例,那麽首先看一下工廠Bean的緩存中有木有實例,如果有就返回,如果沒有,就會調用getObjectFromFactoryBean方法來獲得Bean實例。

復制代碼
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {

    // Don‘t let calling code try to dereference the factory if the bean isn‘t a factory.
    //容器已經得到了Bean實例對象,這個實例對象可能是一個普通的Bean,
    //也可能是一個工廠Bean,如果是一個工廠Bean,則使用它創建一個Bean實例對象,
    //如果調用本身就想獲得一個容器的引用,則指定返回這個工廠Bean實例對象
    //如果指定的名稱是容器的解引用(dereference,即是對象本身而非內存地址),
    //且Bean實例也不是創建Bean實例對象的工廠Bean
    if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
        throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
    }

    // Now we have the bean instance, which may be a normal bean or a FactoryBean.
    // If it‘s a FactoryBean, we use it to create a bean instance, unless the
    // caller actually wants a reference to the factory.
    //如果Bean實例不是工廠Bean,或者指定名稱是容器的解引用,
    //調用者向獲取對容器的引用,則直接返回當前的Bean實例
    if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
        return beanInstance;
    }

    //處理指定名稱不是容器的解引用,或者根據名稱獲取的Bean實例對象是一個工廠Bean
    //使用工廠Bean創建一個Bean的實例對象
    Object object = null;
    if (mbd == null) {
        //從Bean工廠緩存中獲取給定名稱的Bean實例對象
        object = getCachedObjectForFactoryBean(beanName);
    }
    //讓Bean工廠生產給定名稱的Bean對象實例
    if (object == null) {
        // Return bean instance from factory.
        FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
        // Caches object obtained from FactoryBean if it is a singleton.
        //如果從Bean工廠生產的Bean是單態模式的,則緩存
        if (mbd == null && containsBeanDefinition(beanName)) {
            //從容器中獲取指定名稱的Bean定義,如果繼承基類,則合並基類相關屬性
            mbd = getMergedLocalBeanDefinition(beanName);
        }
        //如果從容器得到Bean定義信息,並且Bean定義信息不是虛構的,
        //則讓工廠Bean生產Bean實例對象
        boolean synthetic = (mbd != null && mbd.isSynthetic());
        //調用FactoryBeanRegistrySupport類的getObjectFromFactoryBean方法,
        //實現工廠Bean生產Bean對象實例的過程
        object = getObjectFromFactoryBean(factory, beanName, !synthetic);
    }
    return object;
}

復制代碼
接下來我們看一看是怎麽從FactoryBean裏拿到Bean實例的,先進入getObjectFromFactoryBean方法。

復制代碼
//Bean工廠生產Bean實例對象
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
//Bean工廠是單態模式,並且Bean工廠緩存中存在指定名稱的Bean實例對象
if (factory.isSingleton() && containsSingleton(beanName)) {
//多線程同步,以防止數據不一致
synchronized (getSingletonMutex()) {
//直接從Bean工廠緩存中獲取指定名稱的Bean實例對象
Object object = this.factoryBeanObjectCache.get(beanName);
//Bean工廠緩存中沒有指定名稱的實例對象,則生產該實例對象
if (object == null) {
//調用Bean工廠的getObject方法生產指定Bean的實例對象
object = doGetObjectFromFactoryBean(factory, beanName);
// Only post-process and store if not put there already during getObject() call above
// (e.g. because of circular reference processing triggered by custom getBean calls)
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
if (alreadyThere != null) {
object = alreadyThere;
}
else {
if (shouldPostProcess) {
try {
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Post-processing of FactoryBean‘s singleton object failed", ex);
}
}
//將生產的實例對象添加到Bean工廠緩存中
this.factoryBeanObjectCache.put(beanName, object);
}
}
return object;
}
}
//調用Bean工廠的getObject方法生產指定Bean的實例對象
else {
Object object = doGetObjectFromFactoryBean(factory, beanName);
if (shouldPostProcess) {
try {
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Post-processing of FactoryBean‘s object failed", ex);
}
}
return object;
}
}
復制代碼
由於我們現在創建的Bean為單例模式,所以要保證線程安全,首先先判斷在FactoryBean裏有沒有該Bean的緩存,如果沒有就自己創建,方法為doGetBeanFromFactoryBean,並且將創建好的Bean存到Cache裏。那麽我們到現在又看到了一個做實事的方法,看名字這個方法應該是生產Bean的方法。

復制代碼
//調用Bean工廠的getObject方法生產指定Bean的實例對象
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
throws BeanCreationException {

    Object object;
    try {
        if (System.getSecurityManager() != null) {
            AccessControlContext acc = getAccessControlContext();
            try {
                //實現PrivilegedExceptionAction接口的匿名內置類
                //根據JVM檢查權限,然後決定BeanFactory創建實例對象
                object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () ->
                        factory.getObject(), acc);
            }
            catch (PrivilegedActionException pae) {
                throw pae.getException();
            }
        }
        else {
            //調用BeanFactory接口實現類的創建對象方法
            object = factory.getObject();
        }
    }
    catch (FactoryBeanNotInitializedException ex) {
        throw new BeanCurrentlyInCreationException(beanName, ex.toString());
    }
    catch (Throwable ex) {
        throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
    }

    // Do not accept a null value for a FactoryBean that‘s not fully
    // initialized yet: Many FactoryBeans just return null then.
    //創建出來的實例對象為null,或者因為單態對象正在創建而返回null
    if (object == null) {
        if (isSingletonCurrentlyInCreation(beanName)) {
            throw new BeanCurrentlyInCreationException(
                    beanName, "FactoryBean which is currently in creation returned null from getObject");
        }
        object = new NullBean();
    }
    return object;
}

復制代碼
通過這個方法,我們就得到了單例Bean的實例(不管它有沒有在Cache裏存在)。

同樣,如果緩存中沒有被創建的Bean,那麽在之前那段代碼中(doGetBean),就不會走31行那一塊,而是接著往下走,到101行,執行到createBean方法,這裏用到了lamda表達式,new了一個內部類objectFactory。

復制代碼//AbstractAutowireCapableBeanFactory.class
//創建Bean實例對象
@Override
br/>//AbstractAutowireCapableBeanFactory.class
//創建Bean實例對象
@Override
throws BeanCreationException {

    if (logger.isDebugEnabled()) {
        logger.debug("Creating instance of bean ‘" + beanName + "‘");
    }
    RootBeanDefinition mbdToUse = mbd;

    // Make sure bean class is actually resolved at this point, and
    // clone the bean definition in case of a dynamically resolved Class
    // which cannot be stored in the shared merged bean definition.
    //判斷需要創建的Bean是否可以實例化,即是否可以通過當前的類加載器加載
    Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
    if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
        mbdToUse = new RootBeanDefinition(mbd);
        mbdToUse.setBeanClass(resolvedClass);
    }

    // Prepare method overrides.
    //校驗和準備Bean中的方法覆蓋
    try {
        mbdToUse.prepareMethodOverrides();
    }
    catch (BeanDefinitionValidationException ex) {
        throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
                beanName, "Validation of method overrides failed", ex);
    }

    try {
        // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
        //如果Bean配置了初始化前和初始化後的處理器,則試圖返回一個需要創建Bean的代理對象
        Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
        if (bean != null) {
            return bean;
        }
    }
    catch (Throwable ex) {
        throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
                "BeanPostProcessor before instantiation of bean failed", ex);
    }

    try {
        //創建Bean的入口
        Object beanInstance = doCreateBean(beanName, mbdToUse, args);
        if (logger.isDebugEnabled()) {
            logger.debug("Finished creating instance of bean ‘" + beanName + "‘");
        }
        return beanInstance;
    }
    catch (BeanCreationException ex) {
        // A previously detected exception with proper bean creation context already...
        throw ex;
    }
    catch (ImplicitlyAppearedSingletonException ex) {
        // An IllegalStateException to be communicated up to DefaultSingletonBeanRegistry...
        throw ex;
    }
    catch (Throwable ex) {
        throw new BeanCreationException(
                mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
    }
}

復制代碼
在這裏,會調用doCreateBean方法

復制代碼
//AbstractAutowireCapableBeanFactory.class
//真正創建Bean的方法
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {

    // Instantiate the bean.
    //封裝被創建的Bean對象
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
    if (instanceWrapper == null) {
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    final Object bean = instanceWrapper.getWrappedInstance();
    //獲取實例化對象的類型
    Class<?> beanType = instanceWrapper.getWrappedClass();
    if (beanType != NullBean.class) {
        mbd.resolvedTargetType = beanType;
    }

    // Allow post-processors to modify the merged bean definition.
    //調用PostProcessor後置處理器
    synchronized (mbd.postProcessingLock) {
        if (!mbd.postProcessed) {
            try {
                applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
            }
            catch (Throwable ex) {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                        "Post-processing of merged bean definition failed", ex);
            }
            mbd.postProcessed = true;
        }
    }

    // Eagerly cache singletons to be able to resolve circular references
    // even when triggered by lifecycle interfaces like BeanFactoryAware.
    //向容器中緩存單例模式的Bean對象,以防循環引用
    boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
            isSingletonCurrentlyInCreation(beanName));
    if (earlySingletonExposure) {
        if (logger.isDebugEnabled()) {
            logger.debug("Eagerly caching bean ‘" + beanName +
                    "‘ to allow for resolving potential circular references");
        }
        //這裏是一個匿名內部類,為了防止循環引用,盡早持有對象的引用
        addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    }

    // Initialize the bean instance.
    //Bean對象的初始化,依賴註入在此觸發
    //這個exposedObject在初始化完成之後返回作為依賴註入完成後的Bean
    Object exposedObject = bean;
    try {
        //將Bean實例對象封裝,並且Bean定義中配置的屬性值賦值給實例對象
        populateBean(beanName, mbd, instanceWrapper);
        //初始化Bean對象
        exposedObject = initializeBean(beanName, exposedObject, mbd);
    }
    catch (Throwable ex) {
        if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
            throw (BeanCreationException) ex;
        }
        else {
            throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
        }
    }

    if (earlySingletonExposure) {
        //獲取指定名稱的已註冊的單例模式Bean對象
        Object earlySingletonReference = getSingleton(beanName, false);
        if (earlySingletonReference != null) {
            //根據名稱獲取的已註冊的Bean和正在實例化的Bean是同一個
            if (exposedObject == bean) {
                //當前實例化的Bean初始化完成
                exposedObject = earlySingletonReference;
            }
            //當前Bean依賴其他Bean,並且當發生循環引用時不允許新創建實例對象
            else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                String[] dependentBeans = getDependentBeans(beanName);
                Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
                //獲取當前Bean所依賴的其他Bean
                for (String dependentBean : dependentBeans) {
                    //對依賴Bean進行類型檢查
                    if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                        actualDependentBeans.add(dependentBean);
                    }
                }
                if (!actualDependentBeans.isEmpty()) {
                    throw new BeanCurrentlyInCreationException(beanName,
                            "Bean with name ‘" + beanName + "‘ has been injected into other beans [" +
                            StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
                            "] in its raw version as part of a circular reference, but has eventually been " +
                            "wrapped. This means that said other beans do not use the final version of the " +
                            "bean. This is often the result of over-eager type matching - consider using " +
                            "‘getBeanNamesOfType‘ with the ‘allowEagerInit‘ flag turned off, for example.");
                }
            }
        }
    }

    // Register bean as disposable.
    //註冊完成依賴註入的Bean
    try {
        registerDisposableBeanIfNecessary(beanName, bean, mbd);
    }
    catch (BeanDefinitionValidationException ex) {
        throw new BeanCreationException(
                mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
    }

    return exposedObject;
}

復制代碼
這裏首先創建一個包裝類,用到了BeanWrapper來包裝Bean,然後到createBeanInstance方法使得生成一個Bean的Wrapper類。並保證容器緩存中有此Bean對象的單例模式。然後調用populateBean方法,將BeanDefinition的屬性賦值給實例對象,並調用initializeBean方法初始化Bean對象。並對Bean對象進行一系列的檢查,然後返回生成的Bean。

首先我們先看一下createBeanInstance方法,這個方法返回的是一個BeanWrapper對象,首先確定Bean是可以實例化的,然後就對Bean進行實例化。實例化的方法有三種:(1)工廠方法 (2)容器自動裝配 (3)Bean的構造方法

復制代碼
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// Make sure bean class is actually resolved at this point.
//檢查確認Bean是可實例化的
Class<?> beanClass = resolveBeanClass(mbd, beanName);

    //使用工廠方法對Bean進行實例化
    if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                "Bean class isn‘t public, and non-public access not allowed: " + beanClass.getName());
    }

    Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
    if (instanceSupplier != null) {
        return obtainFromSupplier(instanceSupplier, beanName);
    }

    if (mbd.getFactoryMethodName() != null)  {
        //調用工廠方法實例化
        return instantiateUsingFactoryMethod(beanName, mbd, args);
    }

    // Shortcut when re-creating the same bean...
    //使用容器的自動裝配方法進行實例化
    boolean resolved = false;
    boolean autowireNecessary = false;
    if (args == null) {
        synchronized (mbd.constructorArgumentLock) {
            if (mbd.resolvedConstructorOrFactoryMethod != null) {
                resolved = true;
                autowireNecessary = mbd.constructorArgumentsResolved;
            }
        }
    }
    if (resolved) {
        if (autowireNecessary) {
            //配置了自動裝配屬性,使用容器的自動裝配實例化
            //容器的自動裝配是根據參數類型匹配Bean的構造方法
            return autowireConstructor(beanName, mbd, null, null);
        }
        else {
            //使用默認的無參構造方法實例化
            return instantiateBean(beanName, mbd);
        }
    }

    // Need to determine the constructor...
    //使用Bean的構造方法進行實例化
    Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
    if (ctors != null ||
            mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
            mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
        //使用容器的自動裝配特性,調用匹配的構造方法實例化
        return autowireConstructor(beanName, mbd, ctors, args);
    }

    // No special handling: simply use no-arg constructor.
    //使用默認的無參構造方法實例化
    return instantiateBean(beanName, mbd);
}

復制代碼
首先是工廠方法實例化Bean,調用的是instantiateUsingFactoryMethod方法,這邊不詳細分析了。

之後是使用容器自動裝配來進行實例化,如果匹配了自動裝配屬性,那麽久使用容器自動裝配實例化,如果沒有,則用構造方法進行實例化,這裏說一下用構造方法進行實例化的過程

無參構造方法instantiateBean方法,這裏就是實例Bean的方法。

復制代碼
//使用默認的無參構造方法實例化Bean對象
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
try {
Object beanInstance;
final BeanFactory parent = this;
//獲取系統的安全管理接口,JDK標準的安全管理API
if (System.getSecurityManager() != null) {
//這裏是一個匿名內置類,根據實例化策略創建實例對象
beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
getInstantiationStrategy().instantiate(mbd, beanName, parent),
getAccessControlContext());
}
else {
//將實例化的對象封裝起來
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}
復制代碼
首先實例對象,用到的是instantiate方法,然後再將其包裝成BeanWrapper

然後到instantiate方法。

復制代碼//使用初始化策略實例化Bean對象
@Override
br/>//使用初始化策略實例化Bean對象
@Override
// Don‘t override the class with CGLIB if no overrides.
//如果Bean定義中沒有方法覆蓋,則就不需要CGLIB父類類的方法
if (!bd.hasMethodOverrides()) {
Constructor<?> constructorToUse;
synchronized (bd.constructorArgumentLock) {
//獲取對象的構造方法或工廠方法
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
//如果沒有構造方法且沒有工廠方法
if (constructorToUse == null) {
//使用JDK的反射機制,判斷要實例化的Bean是否是接口
final Class<?> clazz = bd.getBeanClass();
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
if (System.getSecurityManager() != null) {
//這裏是一個匿名內置類,使用反射機制獲取Bean的構造方法
constructorToUse = AccessController.doPrivileged(
(PrivilegedExceptionAction<Constructor<?>>) () -> clazz.getDeclaredConstructor());
}
else {
constructorToUse = clazz.getDeclaredConstructor();
}
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch (Throwable ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
//使用BeanUtils實例化,通過反射機制調用”構造方法.newInstance(arg)”來進行實例化
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// Must generate CGLIB subclass.
//使用CGLIB來實例化對象
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
復制代碼
首先檢查Bean中有沒有覆蓋父類方法,如果沒有的話,就不用CGLIB父類類的方法,然後通過反射獲得Bean的構造方法,之後通過BeanUtils使用構造方法進行實例化。如果有覆蓋方法,那麽就要使用CGLIB來進行實例化

然後調用instantiateWithMethodInjection方法

@Override
protected Object instantiateWithMethodInjection(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
return instantiateWithMethodInjection(bd, beanName, owner, null);}
@Override
br/>}
@Override
@Nullable Constructor<?> ctor, @Nullable Object... args) {

    // Must generate CGLIB subclass...
    return new CglibSubclassCreator(bd, owner).instantiate(ctor, args);
}

到這裏可以看到調用使用CGLIB的instantiate方法。

復制代碼
public Object instantiate(@Nullable Constructor<?> ctor, @Nullable Object... args) {
//創建代理子類
Class<?> subclass = createEnhancedSubclass(this.beanDefinition);
Object instance;
if (ctor == null) {
instance = BeanUtils.instantiateClass(subclass);
}
else {
try {
Constructor<?> enhancedSubclassConstructor = subclass.getConstructor(ctor.getParameterTypes());
instance = enhancedSubclassConstructor.newInstance(args);
}
catch (Exception ex) {
throw new BeanInstantiationException(this.beanDefinition.getBeanClass(),
"Failed to invoke constructor for CGLIB enhanced subclass [" + subclass.getName() + "]", ex);
}
}
// SPR-10785: set callbacks directly on the instance instead of in the
// enhanced class (via the Enhancer) in order to avoid memory leaks.
Factory factory = (Factory) instance;
factory.setCallbacks(new Callback[] {NoOp.INSTANCE,
new LookupOverrideMethodInterceptor(this.beanDefinition, this.owner),
new ReplaceOverrideMethodInterceptor(this.beanDefinition, this.owner)});
return instance;
}
復制代碼
然後調用instantiateClass方法

復制代碼
public static <T> T instantiateClass(Class<T> clazz) throws BeanInstantiationException {
Assert.notNull(clazz, "Class must not be null");
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
Constructor<T> ctor = (KotlinDetector.isKotlinType(clazz) ?
KotlinDelegate.findPrimaryConstructor(clazz) : clazz.getDeclaredConstructor());
if (ctor == null) {
throw new BeanInstantiationException(clazz, "No default constructor found");
}
return instantiateClass(ctor);
}
catch (NoSuchMethodException ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
復制代碼
復制代碼
public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
Assert.notNull(ctor, "Constructor must not be null");
try {
ReflectionUtils.makeAccessible(ctor);
return (KotlinDetector.isKotlinType(ctor.getDeclaringClass()) ?
KotlinDelegate.instantiateClass(ctor, args) : ctor.newInstance(args));
}
catch (InstantiationException ex) {
throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex);
}
catch (IllegalAccessException ex) {
throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex);
}
catch (IllegalArgumentException ex) {
throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex);
}
catch (InvocationTargetException ex) {
throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException());
}
}
復制代碼
回到instantiateBean方法,我們得到了實例化的Bean對象,那麽接下來就是將他封裝起來。調用了BeanWrapperImpl的構造方法,並初始化這個BeanWrapper然後將其返回。

之後回到createBeanInstance方法,剛才介紹的是用無參構造函數方法將其進行實例化封裝,接下來如果有參數,那麽就會使用容器的自動裝配特性,調用匹配的構造方法進行實例化。

再回到之前調用createBeanInstance方法的時候,也就是在AbstractAutowireCapableBeanFactory這個類裏的doCreateBean方法中,會調用populateBean方法,這裏就是真正的依賴註入。

復制代碼
1 //將Bean屬性設置到生成的實例對象上
2 protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
3 if (bw == null) {
4 if (mbd.hasPropertyValues()) {
5 throw new BeanCreationException(
6 mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
7 }
8 else {
9 // Skip property population phase for null instance.
10 return;
11 }
12 }
13
14 // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
15 // state of the bean before properties are set. This can be used, for example,
16 // to support styles of field injection.
17 boolean continueWithPropertyPopulation = true;
18
19 if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
20 for (BeanPostProcessor bp : getBeanPostProcessors()) {
21 if (bp instanceof InstantiationAwareBeanPostProcessor) {
22 InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
23 if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
24 continueWithPropertyPopulation = false;
25 break;
26 }
27 }
28 }
29 }
30
31 if (!continueWithPropertyPopulation) {
32 return;
33 }
34 //獲取容器在解析Bean定義資源時為BeanDefiniton中設置的屬性值
35 PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
36
37 //對依賴註入處理,首先處理autowiring自動裝配的依賴註入
38 if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
39 mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
40 MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
41
42 // Add property values based on autowire by name if applicable.
43 //根據Bean名稱進行autowiring自動裝配處理
44 if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
45 autowireByName(beanName, mbd, bw, newPvs);
46 }
47
48 // Add property values based on autowire by type if applicable.
49 //根據Bean類型進行autowiring自動裝配處理
50 if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
51 autowireByType(beanName, mbd, bw, newPvs);
52 }
53
54 pvs = newPvs;
55 }
56
57 //對非autowiring的屬性進行依賴註入處理
58
59 boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
60 boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
61
62 if (hasInstAwareBpps || needsDepCheck) {
63 if (pvs == null) {
64 pvs = mbd.getPropertyValues();
65 }
66 PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
67 if (hasInstAwareBpps) {
68 for (BeanPostProcessor bp : getBeanPostProcessors()) {
69 if (bp instanceof InstantiationAwareBeanPostProcessor) {
70 InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
71 pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
72 if (pvs == null) {
73 return;
74 }
75 }
76 }
77 }
78 if (needsDepCheck) {
79 checkDependencies(beanName, mbd, filteredPds, pvs);
80 }
81 }
82
83 if (pvs != null) {
84 //對屬性進行註入
85 applyPropertyValues(beanName, mbd, bw, pvs);
86 }
87 }
復制代碼
首先會檢查這個包裝類是否為空,在保證不為空的前提下,首先獲取BeanDefinition中的資源屬性值,然後對其進行自動裝配處理,最後對屬性進行註入。

在populateBean方法的最後,會對屬性進行註入,調用applyPropertyValues方法

復制代碼
//解析並註入依賴屬性的過程
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
if (pvs.isEmpty()) {
return;
}

    //封裝屬性值
    MutablePropertyValues mpvs = null;
    List<PropertyValue> original;

    if (System.getSecurityManager() != null) {
        if (bw instanceof BeanWrapperImpl) {
            //設置安全上下文,JDK安全機制
            ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
        }
    }

    if (pvs instanceof MutablePropertyValues) {
        mpvs = (MutablePropertyValues) pvs;
        //屬性值已經轉換
        if (mpvs.isConverted()) {
            // Shortcut: use the pre-converted values as-is.
            try {
                //為實例化對象設置屬性值
                bw.setPropertyValues(mpvs);
                return;
            }
            catch (BeansException ex) {
                throw new BeanCreationException(
                        mbd.getResourceDescription(), beanName, "Error setting property values", ex);
            }
        }
        //獲取屬性值對象的原始類型值
        original = mpvs.getPropertyValueList();
    }
    else {
        original = Arrays.asList(pvs.getPropertyValues());
    }

    //獲取用戶自定義的類型轉換
    TypeConverter converter = getCustomTypeConverter();
    if (converter == null) {
        converter = bw;
    }
    //創建一個Bean定義屬性值解析器,將Bean定義中的屬性值解析為Bean實例對象的實際值
    BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);

    // Create a deep copy, resolving any references for values.

    //為屬性的解析值創建一個拷貝,將拷貝的數據註入到實例對象中
    List<PropertyValue> deepCopy = new ArrayList<>(original.size());
    boolean resolveNecessary = false;
    for (PropertyValue pv : original) {
        //屬性值不需要轉換
        if (pv.isConverted()) {
            deepCopy.add(pv);
        }
        //屬性值需要轉換
        else {
            String propertyName = pv.getName();
            //原始的屬性值,即轉換之前的屬性值
            Object originalValue = pv.getValue();
            //轉換屬性值,例如將引用轉換為IOC容器中實例化對象引用
            Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
            //轉換之後的屬性值
            Object convertedValue = resolvedValue;
            //屬性值是否可以轉換
            boolean convertible = bw.isWritableProperty(propertyName) &&
                    !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
            if (convertible) {
                //使用用戶自定義的類型轉換器轉換屬性值
                convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
            }
            // Possibly store converted value in merged bean definition,
            // in order to avoid re-conversion for every created bean instance.
            //存儲轉換後的屬性值,避免每次屬性註入時的轉換工作
            if (resolvedValue == originalValue) {
                if (convertible) {
                    //設置屬性轉換之後的值
                    pv.setConvertedValue(convertedValue);
                }
                deepCopy.add(pv);
            }
            //屬性是可轉換的,且屬性原始值是字符串類型,且屬性的原始類型值不是
            //動態生成的字符串,且屬性的原始值不是集合或者數組類型
            else if (convertible && originalValue instanceof TypedStringValue &&
                    !((TypedStringValue) originalValue).isDynamic() &&
                    !(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
                pv.setConvertedValue(convertedValue);
                //重新封裝屬性的值
                deepCopy.add(pv);
            }
            else {
                resolveNecessary = true;
                deepCopy.add(new PropertyValue(pv, convertedValue));
            }
        }
    }
    if (mpvs != null && !resolveNecessary) {
        //標記屬性值已經轉換過
        mpvs.setConverted();
    }

    // Set our (possibly massaged) deep copy.
    //進行屬性依賴註入
    try {
        bw.setPropertyValues(new MutablePropertyValues(deepCopy));
    }
    catch (BeansException ex) {
        throw new BeanCreationException(
                mbd.getResourceDescription(), beanName, "Error setting property values", ex);
    }
}

復制代碼
在這裏核心調用的是resolveValueIfNecessary方法,將BeanDefinition裏的一些屬性解析出來,通過反射new出來一個對象。BeanDefinition相當於保存在內存中的配置文件,保存著所有跟這個類屬性相關的信息,依賴註入就是把BeanDefinition這個信息讀出來,通過反射機制或者代理等機制創建對象。一個Bean對應著一個BeanDefinition

新創建的對象不會放在IOC容器裏,而是會存入到另外一個cache容器。IOC容器存放的是一個關系。

復制代碼//BeanDefinitionValueResolver.class
//解析屬性值,對註入類型進行轉換
@Nullable
br/>//BeanDefinitionValueResolver.class
//解析屬性值,對註入類型進行轉換
@Nullable
// We must check each value to see whether it requires a runtime reference
// to another bean to be resolved.
//對引用類型的屬性進行解析
if (value instanceof RuntimeBeanReference) {
RuntimeBeanReference ref = (RuntimeBeanReference) value;
//調用引用類型屬性的解析方法
return resolveReference(argName, ref);
}
//對屬性值是引用容器中另一個Bean名稱的解析
else if (value instanceof RuntimeBeanNameReference) {
String refName = ((RuntimeBeanNameReference) value).getBeanName();
refName = String.valueOf(doEvaluate(refName));
//從容器中獲取指定名稱的Bean
if (!this.beanFactory.containsBean(refName)) {
throw new BeanDefinitionStoreException(
"Invalid bean name ‘" + refName + "‘ in bean reference for " + argName);
}
return refName;
}
//對Bean類型屬性的解析,主要是Bean中的內部類
else if (value instanceof BeanDefinitionHolder) {
// Resolve BeanDefinitionHolder: contains BeanDefinition with name and aliases.
BeanDefinitionHolder bdHolder = (BeanDefinitionHolder) value;
return resolveInnerBean(argName, bdHolder.getBeanName(), bdHolder.getBeanDefinition());
}
else if (value instanceof BeanDefinition) {
// Resolve plain BeanDefinition, without contained name: use dummy name.
BeanDefinition bd = (BeanDefinition) value;
String innerBeanName = "(inner bean)" + BeanFactoryUtils.GENERATED_BEAN_NAME_SEPARATOR +
ObjectUtils.getIdentityHexString(bd);
return resolveInnerBean(argName, innerBeanName, bd);
}
//對集合數組類型的屬性解析
else if (value instanceof ManagedArray) {
// May need to resolve contained runtime references.
ManagedArray array = (ManagedArray) value;
//獲取數組的類型
Class<?> elementType = array.resolvedElementType;
if (elementType == null) {
//獲取數組元素的類型
String elementTypeName = array.getElementTypeName();
if (StringUtils.hasText(elementTypeName)) {
try {
//使用反射機制創建指定類型的對象
elementType = ClassUtils.forName(elementTypeName, this.beanFactory.getBeanClassLoader());
array.resolvedElementType = elementType;
}
catch (Throwable ex) {
// Improve the message by showing the context.
throw new BeanCreationException(
this.beanDefinition.getResourceDescription(), this.beanName,
"Error resolving array type for " + argName, ex);
}
}
//沒有獲取到數組的類型,也沒有獲取到數組元素的類型
//則直接設置數組的類型為Object
else {
elementType = Object.class;
}
}
//創建指定類型的數組
return resolveManagedArray(argName, (List<?>) value, elementType);
}
//解析list類型的屬性值
else if (value instanceof ManagedList) {
// May need to resolve contained runtime references.
return resolveManagedList(argName, (List<?>) value);
}
//解析set類型的屬性值
else if (value instanceof ManagedSet) {
// May need to resolve contained runtime references.
return resolveManagedSet(argName, (Set<?>) value);
}
//解析map類型的屬性值
else if (value instanceof ManagedMap) {
// May need to resolve contained runtime references.
return resolveManagedMap(argName, (Map<?, ?>) value);
}
//解析props類型的屬性值,props其實就是key和value均為字符串的map
else if (value instanceof ManagedProperties) {
Properties original = (Properties) value;
//創建一個拷貝,用於作為解析後的返回值
Properties copy = new Properties();
original.forEach((propKey, propValue) -> {
if (propKey instanceof TypedStringValue) {
propKey = evaluate((TypedStringValue) propKey);
}
if (propValue instanceof TypedStringValue) {
propValue = evaluate((TypedStringValue) propValue);
}
if (propKey == null || propValue == null) {
throw new BeanCreationException(
this.beanDefinition.getResourceDescription(), this.beanName,
"Error converting Properties key/value pair for " + argName + ": resolved to null");
}
copy.put(propKey, propValue);
});
return copy;
}
//解析字符串類型的屬性值
else if (value instanceof TypedStringValue) {
// Convert value to target type here.
TypedStringValue typedStringValue = (TypedStringValue) value;
Object valueObject = evaluate(typedStringValue);
try {
//獲取屬性的目標類型
Class<?> resolvedTargetType = resolveTargetType(typedStringValue);
if (resolvedTargetType != null) {
//對目標類型的屬性進行解析,遞歸調用
return this.typeConverter.convertIfNecessary(valueObject, resolvedTargetType);
}
//沒有獲取到屬性的目標對象,則按Object類型返回
else {
return valueObject;
}
}
catch (Throwable ex) {
// Improve the message by showing the context.
throw new BeanCreationException(
this.beanDefinition.getResourceDescription(), this.beanName,
"Error converting typed String value for " + argName, ex);
}
}
else if (value instanceof NullBean) {
return null;
}
else {
return evaluate(value);
}
}
復制代碼
同時,在上個方法中(applyPropertyValues),會調用到bw.setPropertyValues方法,他的作用是為實例化的對象設置屬性

復制代碼@Override
br/>@Override
throws BeansException {

    List<PropertyAccessException> propertyAccessExceptions = null;
    List<PropertyValue> propertyValues = (pvs instanceof MutablePropertyValues ?
            ((MutablePropertyValues) pvs).getPropertyValueList() : Arrays.asList(pvs.getPropertyValues()));
    for (PropertyValue pv : propertyValues) {
        try {
            // This method may throw any BeansException, which won‘t be caught
            // here, if there is a critical failure such as no matching field.
            // We can attempt to deal only with less serious exceptions.
            setPropertyValue(pv);
        }
        catch (NotWritablePropertyException ex) {
            if (!ignoreUnknown) {
                throw ex;
            }
            // Otherwise, just ignore it and continue...
        }
        catch (NullValueInNestedPathException ex) {
            if (!ignoreInvalid) {
                throw ex;
            }
            // Otherwise, just ignore it and continue...
        }
        catch (PropertyAccessException ex) {
            if (propertyAccessExceptions == null) {
                propertyAccessExceptions = new LinkedList<>();
            }
            propertyAccessExceptions.add(ex);
        }
    }

    // If we encountered individual exceptions, throw the composite exception.
    if (propertyAccessExceptions != null) {
        PropertyAccessException[] paeArray =
                propertyAccessExceptions.toArray(new PropertyAccessException[propertyAccessExceptions.size()]);
        throw new PropertyBatchUpdateException(paeArray);
    }
}

復制代碼
主要一點是弄清楚wrapper是怎麽來的。Wrapper對原生對象進行包裝,通過構造方法存儲原始對象,然後放入cache的是Wrapper。

考慮一下為什麽要用到包裝模式:減少代碼侵入,能夠在原生的基礎之上再進行擴展,他可以覆蓋、調用方法,甚至可以在原來的方法之上增加監聽器、回調函數等。包裝模式相當於靜態代理的一種額外模式。

到這兒,Bean的依賴註入就搞定了。總結一下,在我們之前操作的IOC容器初始化後,將XML上的內容轉化為BeanDefinition中的內容,然後通過傳入指定Bean的名字,首先判斷Chache中有沒有,也要查看其父級BeanFactory,如果有,就通過限定名字得到實例,如果沒有,就去創建,創建的方式也分單例和原型兩種。

騰訊分分彩源碼帶龍虎和玩法自言自語Spring依賴註入(XML配置)