通過《spring源碼閱讀(3)-- 容器啟動之BeanFactoryPostProcessor》一文了解到了spring對擴展點BeanFactoryPostProcessor是如何處理的,接下來看看spring是如何創建bean的。進入AbstractApplicationContext.refresh方法
1 public void refresh() throws BeansException, IllegalStateException { 2 synchronized (this.startupShutdownMonitor) { 3 prepareRefresh(); 4 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); 5 prepareBeanFactory(beanFactory); 6 7 try { 8 postProcessBeanFactory(beanFactory); 9 invokeBeanFactoryPostProcessors(beanFactory); 10 registerBeanPostProcessors(beanFactory); 11 initMessageSource(); 12 initApplicationEventMulticaster(); 13 onRefresh(); 14 registerListeners(); 15 finishBeanFactoryInitialization(beanFactory); 16 finishRefresh(); 17 } 18 19 catch (BeansException ex) { 20 if (logger.isWarnEnabled()) { 21 logger.warn("Exception encountered during context initialization - " + 22 "cancelling refresh attempt: " + ex); 23 } 24 destroyBeans(); 25 cancelRefresh(ex); 26 throw ex; 27 } 28 29 finally { 30 resetCommonCaches(); 31 } 32 } 33 }
spring在創建bean前,會先注冊BeanPostProcessor(BeanPostProcessor是spring對外暴露的另一個擴展點,會在spring創建bean前后調用相應的方法,具體參考《Spring探秘|妙用BeanPostProcessor》),然后初始化spring事件傳播相關功能。spring bean的創建入口在finishBeanFactoryInitialization方法,spring在容器初始化時,會先初始化lazy-init=false和單例的bean。
1 protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { 2 // Initialize conversion service for this context. 3 if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) && 4 beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) { 5 beanFactory.setConversionService( 6 beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)); 7 } 8 9 // Register a default embedded value resolver if no bean post-processor 10 // (such as a PropertyPlaceholderConfigurer bean) registered any before: 11 // at this point, primarily for resolution in annotation attribute values. 12 if (!beanFactory.hasEmbeddedValueResolver()) { 13 beanFactory.addEmbeddedValueResolver(new StringValueResolver() { 14 @Override 15 public String resolveStringValue(String strVal) { 16 return getEnvironment().resolvePlaceholders(strVal); 17 } 18 }); 19 } 20 21 // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early. 22 String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false); 23 for (String weaverAwareName : weaverAwareNames) { 24 getBean(weaverAwareName); 25 } 26 27 // Stop using the temporary ClassLoader for type matching. 28 beanFactory.setTempClassLoader(null); 29 30 // Allow for caching all bean definition metadata, not expecting further changes. 31 beanFactory.freezeConfiguration(); 32 33 // Instantiate all remaining (non-lazy-init) singletons. 34 beanFactory.preInstantiateSingletons(); 35 }
finishBeanFactoryInitialization方法里首先判斷是否有包含conversionService名字的bean,如果有先創建。由於我們在配置bean的屬性時,都是以字符串的形式來配置,如下
1 <bean id="test" class="com.zksite.spring.test.SpringBeanTest"> 2 <property name="num" value="1"></property> 3 </bean>
但num的類型不一定是String,有可能是Integer、Boolean、BigDecimal等,conversionService的作用就是將配置的字符串轉為實際的類型,關於更多的conversionService的使用可以參考其他網上資料。
接着finishBeanFactoryInitialization方法12行,首先判斷beanFactory是否有EmbeddedValueResolver,如果沒有,添加一個StringValueResolver。由於DefaultListableBeanFactory實現了ConfigurableBeanFactory,所以當沒有EmbeddedValueResolver時調用resolveEmbeddedValue方法是獲取環境變量。一般我們項目里都會配置指定的配置文件,那么當配置了指定的配置文件時,可以通過resolveEmbeddedValue("${name}")的形式獲取配置文件的內容,更多時候我們會通過@Value注解獲取配置文件的內容,當然這需要更多的配置。
接着創建實現了LoadTimeWeaverAware接口的bean(先忽略LoadTimeWeaverAware的內容),然后緩存所有的bean name。beanFactory.preInstantiateSingletons()開始創建所有的單例bean,進入preInstantiateSingletons方法,方法里首先遍歷beanNames去創建bean,然后回調實現了SmartInitializingSingleton接口的bean的afterSingletonsInstantiated方法
1 public void preInstantiateSingletons() throws BeansException { 2 if (this.logger.isDebugEnabled()) { 3 this.logger.debug("Pre-instantiating singletons in " + this); 4 } 5 6 // Iterate over a copy to allow for init methods which in turn register new bean definitions. 7 // While this may not be part of the regular factory bootstrap, it does otherwise work fine. 8 List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames); 9 10 // Trigger initialization of all non-lazy singleton beans... 11 for (String beanName : beanNames) { 12 RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); 13 if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { 14 if (isFactoryBean(beanName)) { 15 final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName); 16 boolean isEagerInit; 17 if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { 18 isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() { 19 @Override 20 public Boolean run() { 21 return ((SmartFactoryBean<?>) factory).isEagerInit(); 22 } 23 }, getAccessControlContext()); 24 } 25 else { 26 isEagerInit = (factory instanceof SmartFactoryBean && 27 ((SmartFactoryBean<?>) factory).isEagerInit()); 28 } 29 if (isEagerInit) { 30 getBean(beanName); 31 } 32 } 33 else { 34 getBean(beanName); 35 } 36 } 37 } 38 39 // Trigger post-initialization callback for all applicable beans... 40 for (String beanName : beanNames) { 41 Object singletonInstance = getSingleton(beanName); 42 if (singletonInstance instanceof SmartInitializingSingleton) { 43 final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance; 44 if (System.getSecurityManager() != null) { 45 AccessController.doPrivileged(new PrivilegedAction<Object>() { 46 @Override 47 public Object run() { 48 smartSingleton.afterSingletonsInstantiated(); 49 return null; 50 } 51 }, getAccessControlContext()); 52 } 53 else { 54 smartSingleton.afterSingletonsInstantiated(); 55 } 56 } 57 } 58 }
循環體里首選獲取合並的BeanDefinition,為什么需要獲取合並后的BeanDefinition呢?其實只有當我們在配置bean時,如果指定了parent屬性時,getMergedLocalBeanDefinition方法里會遞歸獲取父級BeanDefinition,然后通過getMergedLocalBeanDefinition返回的RootBeanDefinition判斷是否不是抽象的bean並且是單例和非懶加載的,如果這三者都成立,那么再判斷是否是一個FactoryBean(FactoryBean是一個特殊的bean,通過beanName獲取得到的不是FactoryBean本身,最終返回的bean是通過回調FactoryBean.getObject返回的),接着調用getBean方法,getBean方法是通過調用doGetBean方法,直接進入doGetBean方法
1 protected <T> T doGetBean( 2 final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly) 3 throws BeansException { 4 5 final String beanName = transformedBeanName(name); 6 Object bean; 7 8 // Eagerly check singleton cache for manually registered singletons. 9 Object sharedInstance = getSingleton(beanName); 10 if (sharedInstance != null && args == null) { 11 if (logger.isDebugEnabled()) { 12 if (isSingletonCurrentlyInCreation(beanName)) { 13 logger.debug("Returning eagerly cached instance of singleton bean '" + beanName + 14 "' that is not fully initialized yet - a consequence of a circular reference"); 15 } 16 else { 17 logger.debug("Returning cached instance of singleton bean '" + beanName + "'"); 18 } 19 } 20 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); 21 } 22 23 else { 24 // Fail if we're already creating this bean instance: 25 // We're assumably within a circular reference. 26 if (isPrototypeCurrentlyInCreation(beanName)) { 27 throw new BeanCurrentlyInCreationException(beanName); 28 } 29 30 // Check if bean definition exists in this factory. 31 BeanFactory parentBeanFactory = getParentBeanFactory(); 32 if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { 33 // Not found -> check parent. 34 String nameToLookup = originalBeanName(name); 35 if (args != null) { 36 // Delegation to parent with explicit args. 37 return (T) parentBeanFactory.getBean(nameToLookup, args); 38 } 39 else { 40 // No args -> delegate to standard getBean method. 41 return parentBeanFactory.getBean(nameToLookup, requiredType); 42 } 43 } 44 45 if (!typeCheckOnly) { 46 markBeanAsCreated(beanName); 47 } 48 49 try { 50 final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); 51 checkMergedBeanDefinition(mbd, beanName, args); 52 53 // Guarantee initialization of beans that the current bean depends on. 54 String[] dependsOn = mbd.getDependsOn(); 55 if (dependsOn != null) { 56 for (String dependsOnBean : dependsOn) { 57 if (isDependent(beanName, dependsOnBean)) { 58 throw new BeanCreationException(mbd.getResourceDescription(), beanName, 59 "Circular depends-on relationship between '" + beanName + "' and '" + dependsOnBean + "'"); 60 } 61 registerDependentBean(dependsOnBean, beanName); 62 getBean(dependsOnBean); 63 } 64 } 65 66 // Create bean instance. 67 if (mbd.isSingleton()) { 68 sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() { 69 @Override 70 public Object getObject() throws BeansException { 71 try { 72 return createBean(beanName, mbd, args); 73 } 74 catch (BeansException ex) { 75 // Explicitly remove instance from singleton cache: It might have been put there 76 // eagerly by the creation process, to allow for circular reference resolution. 77 // Also remove any beans that received a temporary reference to the bean. 78 destroySingleton(beanName); 79 throw ex; 80 } 81 } 82 }); 83 bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); 84 } 85 86 else if (mbd.isPrototype()) { 87 // It's a prototype -> create a new instance. 88 Object prototypeInstance = null; 89 try { 90 beforePrototypeCreation(beanName); 91 prototypeInstance = createBean(beanName, mbd, args); 92 } 93 finally { 94 afterPrototypeCreation(beanName); 95 } 96 bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); 97 } 98 99 else { 100 String scopeName = mbd.getScope(); 101 final Scope scope = this.scopes.get(scopeName); 102 if (scope == null) { 103 throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'"); 104 } 105 try { 106 Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() { 107 @Override 108 public Object getObject() throws BeansException { 109 beforePrototypeCreation(beanName); 110 try { 111 return createBean(beanName, mbd, args); 112 } 113 finally { 114 afterPrototypeCreation(beanName); 115 } 116 } 117 }); 118 bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); 119 } 120 catch (IllegalStateException ex) { 121 throw new BeanCreationException(beanName, 122 "Scope '" + scopeName + "' is not active for the current thread; consider " + 123 "defining a scoped proxy for this bean if you intend to refer to it from a singleton", 124 ex); 125 } 126 } 127 } 128 catch (BeansException ex) { 129 cleanupAfterBeanCreationFailure(beanName); 130 throw ex; 131 } 132 } 133 134 // Check if required type matches the type of the actual bean instance. 135 if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) { 136 try { 137 return getTypeConverter().convertIfNecessary(bean, requiredType); 138 } 139 catch (TypeMismatchException ex) { 140 if (logger.isDebugEnabled()) { 141 logger.debug("Failed to convert bean '" + name + "' to required type [" + 142 ClassUtils.getQualifiedName(requiredType) + "]", ex); 143 } 144 throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); 145 } 146 } 147 return (T) bean; 148 }
這個方法有點長,方法里第一步調用transformedBeanName改造bean name,transformedBeanName首先判斷name是以“&”開頭,如果是去掉,返回真正的bane name,接着判斷傳入的name是否是別名,bean的創建都是通過bean name去創建,所以通過transformedBeanName方法返回的是最終的bean name。得到bean name之后,首先嘗試通過getSingleton方法獲取bean,這是為了解決循環依賴,這里先不看是具體怎么解決循環依賴的,后面會提到。如果通過getSingleton方法返回的對象不為空,進去getObjectForBeanInstance()方法,getObjectForBeanInstance處理的主要內容是針對當前的bean是一個FactoryBean,關於FactoryBean先殘忍得忽略。
當getSingleton返回的的對象為空時,開始創建bean,如果當前的beanFactory的parentFactory不為空,那么創建bean是會委派給parentFactory去做。創建前會做一些前置檢查,分別有判斷當前創建的bean是否正在創建,是否是一個抽象bean。當這些檢查通過時,首先初始化當前bean依賴的bean。不管是單例的bean還是原型的bean都是通過createBean方法去創建,只不過當是一個單例的bean時,可能在創建前后會做一些其它處理,例如解決循環依賴和將已創建的bean緩存。進入DefaultSingletonBeanRegistry.getSingleton方法,DefaultSingletonBeanRegistry是SingletonBeanRegistry的默認實現,通過類名發現這是一個單例bean的注冊中心,SingletonBeanRegistry接口定義了單例bean的注冊,和獲取單例bean等接口,但真正的創建bean,SingletonBeanRegistry沒有定義而是由AbstractBeanFactory定義,實現是AbstractAutowireCapableBeanFactory,我們當前使用的DefaultListableBeanFactory都直接或間接實現了這些接口。

1 public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { 2 Assert.notNull(beanName, "'beanName' must not be null"); 3 synchronized (this.singletonObjects) { 4 Object singletonObject = this.singletonObjects.get(beanName); 5 if (singletonObject == null) { 6 if (this.singletonsCurrentlyInDestruction) { 7 throw new BeanCreationNotAllowedException(beanName, 8 "Singleton bean creation not allowed while the singletons of this factory are in destruction " + 9 "(Do not request a bean from a BeanFactory in a destroy method implementation!)"); 10 } 11 if (logger.isDebugEnabled()) { 12 logger.debug("Creating shared instance of singleton bean '" + beanName + "'"); 13 } 14 beforeSingletonCreation(beanName); 15 boolean newSingleton = false; 16 boolean recordSuppressedExceptions = (this.suppressedExceptions == null); 17 if (recordSuppressedExceptions) { 18 this.suppressedExceptions = new LinkedHashSet<Exception>(); 19 } 20 try { 21 singletonObject = singletonFactory.getObject(); 22 newSingleton = true; 23 } 24 catch (IllegalStateException ex) { 25 // Has the singleton object implicitly appeared in the meantime -> 26 // if yes, proceed with it since the exception indicates that state. 27 singletonObject = this.singletonObjects.get(beanName); 28 if (singletonObject == null) { 29 throw ex; 30 } 31 } 32 catch (BeanCreationException ex) { 33 if (recordSuppressedExceptions) { 34 for (Exception suppressedException : this.suppressedExceptions) { 35 ex.addRelatedCause(suppressedException); 36 } 37 } 38 throw ex; 39 } 40 finally { 41 if (recordSuppressedExceptions) { 42 this.suppressedExceptions = null; 43 } 44 afterSingletonCreation(beanName); 45 } 46 if (newSingleton) { 47 addSingleton(beanName, singletonObject); 48 } 49 } 50 return (singletonObject != NULL_OBJECT ? singletonObject : null); 51 } 52 }
方法里首先從singletonObjects這個Map里面獲取,如果當前獲取的bean已創建,singletonObjects返回的的值不為空,然后直接返回給上層。當從singletonObjects獲取不到指定的值時,這時需要創建一個,創建前調用beforeSingletonCreation,這個方法里有兩個作用,分別是判斷當前創建的bean是否正在創建和使用一個set將當前創建的bean name保存起來為了解決循環依賴。然后調用singletonFactory.getObject創建bean,當創建bean成功時會刪除之前使用set保存的當前創建bean name並將bean緩存在一個map里。singletonFactory.getObject是通過調用AbstractAutowireCapableBeanFactory.createBean創建bean實例,進入createBean方法
1 protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException { 2 if (logger.isDebugEnabled()) { 3 logger.debug("Creating instance of bean '" + beanName + "'"); 4 } 5 RootBeanDefinition mbdToUse = mbd; 6 7 // Make sure bean class is actually resolved at this point, and 8 // clone the bean definition in case of a dynamically resolved Class 9 // which cannot be stored in the shared merged bean definition. 10 Class<?> resolvedClass = resolveBeanClass(mbd, beanName); 11 if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { 12 mbdToUse = new RootBeanDefinition(mbd); 13 mbdToUse.setBeanClass(resolvedClass); 14 } 15 16 // Prepare method overrides. 17 try { 18 mbdToUse.prepareMethodOverrides(); 19 } 20 catch (BeanDefinitionValidationException ex) { 21 throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), 22 beanName, "Validation of method overrides failed", ex); 23 } 24 25 try { 26 // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance. 27 Object bean = resolveBeforeInstantiation(beanName, mbdToUse); 28 if (bean != null) { 29 return bean; 30 } 31 } 32 catch (Throwable ex) { 33 throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, 34 "BeanPostProcessor before instantiation of bean failed", ex); 35 } 36 37 Object beanInstance = doCreateBean(beanName, mbdToUse, args); 38 if (logger.isDebugEnabled()) { 39 logger.debug("Finished creating instance of bean '" + beanName + "'"); 40 } 41 return beanInstance; 42 }
方法里首先調用resolveBeanClass方法獲取bean的calss,通過查看resolveBeanClass方法,可以發現,bean的class屬性可以配置為spl表達式。接着就是校驗lookup-method和replaced-method,檢查創建的bean是否有指定的方法。當這些准備工作做完時,嘗試通過配置的InstantiationAwareBeanPostProcessor去創建實例, 如果存在InstantiationAwareBeanPostProcessor並創建了實例,調用所有的BeanPostProcessor.postProcessAfterInitialization完成bean的創建並返回。如果沒有調用doCreateBean執行創建bean實例。
1 BeanWrapper instanceWrapper = null; 2 if (mbd.isSingleton()) { 3 instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); 4 } 5 if (instanceWrapper == null) { 6 instanceWrapper = createBeanInstance(beanName, mbd, args); 7 }
方法里首先通過緩存獲取BeanWrapper實例,spring使用BeanWrapper定義了一個標准javaBean的操作。如果緩存不存在調用createBeanInstance方法創建實例。進入createBeanInstance方法
1 protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) { 2 // Make sure bean class is actually resolved at this point. 3 Class<?> beanClass = resolveBeanClass(mbd, beanName); 4 5 if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) { 6 throw new BeanCreationException(mbd.getResourceDescription(), beanName, 7 "Bean class isn't public, and non-public access not allowed: " + beanClass.getName()); 8 } 9 10 if (mbd.getFactoryMethodName() != null) { 11 return instantiateUsingFactoryMethod(beanName, mbd, args); 12 } 13 14 // Shortcut when re-creating the same bean... 15 boolean resolved = false; 16 boolean autowireNecessary = false; 17 if (args == null) { 18 synchronized (mbd.constructorArgumentLock) { 19 //resolvedConstructorOrFactoryMethod用於緩存構造方法或者factoryMethod 20 //只有當創建的bean是scope=prototype,並且在第二次getBean時resolvedConstructorOrFactoryMethod的值才不會為空 21 if (mbd.resolvedConstructorOrFactoryMethod != null) { 22 resolved = true; 23 //constructorArgumentsResolved用於標識是否解決了構造器法參數 24 autowireNecessary = mbd.constructorArgumentsResolved; 25 } 26 } 27 } 28 if (resolved) { 29 if (autowireNecessary) { 30 return autowireConstructor(beanName, mbd, null, null); 31 } 32 else { 33 return instantiateBean(beanName, mbd); 34 } 35 } 36 37 // Need to determine the constructor... 38 Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); 39 if (ctors != null || 40 mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR || 41 mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { 42 return autowireConstructor(beanName, mbd, ctors, args); 43 } 44 45 // No special handling: simply use no-arg constructor. 46 return instantiateBean(beanName, mbd); 47 }
從實現邏輯可以看出,創建bean實例的有三種方式:工廠方法、自動裝配構造器實例化、默認構造器實例化,分別對應不同的方法:
instantiateUsingFactoryMethod:當配置了factory-method屬性時
autowireConstructor:當配置了constructor-arg屬性時
instantiateBean:使用默認的構造器創建實例
instantiateUsingFactoryMethod方法和autowireConstructor放在創建流程其實差不多,大體流程以下,更詳細可以參考源碼
1.找出對應的方法或構造器
2.獲取方法參數值數組
3.計算參數與值的權重,獲取最優構造器或方法。(具體實現挺有意思的)
4.當獲取到構造器或方法后,通過CglibSubclassingInstantiationStrategy創建實例,具體和instantiateBean方法一樣。
instantiateBean默認構造器實例化
當使用的是默認的構造器實例化時,會使用BeanFactory持有的CglibSubclassingInstantiationStrategy實例去創建實例。如果當前的bean使用了方法注入會使用cglib生生成代理對象並返回。否則直接獲取默認的無參構造器,然后通過構造器創建實例並返回。
至此spring已經完成了單例bean的初始化。當bean初始化后,如果當前的bean是一個單例的bean,spring會馬上將bean臨時緩存起來,用於解決循環依賴,由此可以看出,spring只對視單例的bean提供循環依賴的支持。
1 boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && 2 isSingletonCurrentlyInCreation(beanName)); 3 if (earlySingletonExposure) { 4 if (logger.isDebugEnabled()) { 5 logger.debug("Eagerly caching bean '" + beanName + 6 "' to allow for resolving potential circular references"); 7 } 8 addSingletonFactory(beanName, new ObjectFactory<Object>() { 9 @Override 10 public Object getObject() throws BeansException { 11 return getEarlyBeanReference(beanName, mbd, bean); 12 } 13 }); 14 }
當解決完循環依賴之后,接着便是屬性的注入和回調前后置處理。
1 //屬性注入 2 populateBean(beanName, mbd, instanceWrapper); 3 if (exposedObject != null) { 4 //處理回調 5 exposedObject = initializeBean(beanName, exposedObject, mbd); 6 }