首先說一點,由於Spring中的對象默認爲單例,想要獲取它默認init_lazy默認爲false。html
下面的圖是整個流程的流程圖,下面跟的源碼解析就是按照這個流程來的。web
至於基於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方法:session
在以前的文章中提到過,Spring中作實事的方法都是以do開頭的,咱們能夠看到,在getBean方法中調用了一個doGetBean方法,看名字能夠了解到是真正拿到Bean的方法,在doGetBean方法中,首先先將咱們傳進來的指定的名字轉化爲管理Bean的名字,而後再建立一個名爲bean的Object對象,做爲咱們要返回的實例。因爲咱們依賴注入的對象爲單例,因此咱們要作的就是首先在cache中檢查有沒有已經建立好的實例。(Spring中從BeanDefinition建立的Bean不是存放在IOC中,而是存放在Cache容器中,IOC只是存放Bean關係),若是有Bean存在,就直接返回,若是Cache中沒有這個Bean,那麼就要建立它。多線程
在咱們要本身建立Bean的時候,首先先檢查這個Bean有沒有相關的BeanDefinition,首先要解析出Bean的原始名稱,而後如今當前BeanFactory裏檢查,若是沒有,就去父BeanFactory裏面找,若是仍是找不到則沿着容器的繼承體系向父級容器查找。噹噹前容器的父親容器存在並且在當前容器中找不到這個bean時,就開始在父容器裏找,會找父級BeanFactory的getBean方法。app
若是在當前的Bean裏面有,則首先向容器中標記這個Bean已經被建立了,而後根據指定Bean名稱獲取其父級的Bean定義,主要解決Bean繼承時子類合併父類公共屬性問題。接着獲取該Bean全部依賴Bean的名稱,若是有依賴Bean存在,那麼就遞歸獲取依賴Bean,並將依賴Bean註冊給當前的Bean。less
針對於Bean的類型(單例仍是原型),Spring在建立Bean的過程都不同,先看若是建立單例Bean的方法,首先看一下Spring在這是怎麼處理的,它先使用一個內部匿名類,就是一個SingletonFactory類,而後將Bean實際名、Bean的BeanDefinition和Bean參數傳入createBean方法(在下面會分析細節分析這個方法,這邊只是大體過一下doGetBean方法)。並返回建立出的Bean實例。一樣的,若是是一個原型Bean,由於每次都會創建一個新的實例,而後將得到的實例返回給以前建立的bean。若是Bean既不是單例,也不是原型的話,那麼就要根據Bean定義資源中配置的生命週期範圍來選擇合適的實例化Bean方法(這種狀況出如今web那塊比較多,如session,reques等)。ide
最後要對建立好的Bean進行檢查,若是符合規範,就認爲建立好了而且返回。
//AbstractBeanFactory.class //獲取IOC容器中指定名稱的Bean @Override public Object getBean(String name) throws BeansException { //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 protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) 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 public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) { // 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 protected Object instantiateWithMethodInjection(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner, @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 public Object resolveValueIfNecessary(Object argName, @Nullable Object value) { // 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 public void setPropertyValues(PropertyValues pvs, boolean ignoreUnknown, boolean ignoreInvalid) 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,若是有,就經過限定名字獲得實例,若是沒有,就去建立,建立的方式也分單例和原型兩種。