業務系統通過直接或間接調用 BeanFactory#getBean(String) 獲取bean 實例化后的對象。先從 BeanDefinition 配置中獲取類類型信息,然后通過反射創建對象。創建對象后,填充屬性信息,執行 Aware 接口對應的方法,執行 BeanPostProcessor#postProcessBeforeInitialization 方法,調用配置的 init-method 方法,執行 BeanPostProcessor#postProcessAfterInitialization 方法,得到最終的封裝過的 Bean 對象實例。業務系統停機時,調用 destroy-method 銷毀對象相關信息。
一. ApplicationContext 中 獲取 Bean 實例
AbstractApplicationContext#getBean(java.lang.String)
1. 檢查 上下文環境 (ApplicationContext)活動標記是否正常。
2. 通過 BeanFactory 實例獲取 bean 對象。
1 @Override 2 public Object getBean(String name) throws BeansException { 3 assertBeanFactoryActive(); 4 return getBeanFactory().getBean(name); 5 }
二. BeanFactory 獲取 Bean 實例
AbstractBeanFactory#getBean(java.lang.String)
--> AbstractBeanFactory#doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
1.將 name 名稱轉換成 原始的BeanName 名稱。例如:如果 name 有 FACTORY_BEAN_PREFIX 標志,則循環處理去掉。如果是別名,則轉換成實際的 BeanName。
2.從單例緩存中獲取 創建好的共享單例對象。
3.如果獲取的 共享單例對象不為 null。則 通過 getObjectForBeanInstance 方法處理 共享單例對象。
getObjectForBeanInstance():檢查 Bean 實例是否是 FactoryBean 實現類,如果是,則進行相關處理。FactoryBean 是一個返回特殊Bean實例的接口。當運行程序需要簡單生成 Bean 實例時,可以繼承這個接口,實現簡單的三個方法就行。由 FactoryBean 生成的 Bean 實例是沒有復雜的生命周期管理。
4.不滿足 3 條件,則常規邏輯創建 bean 實例。
a. 檢查 beanName 是否是 原型模式 的循環依賴創建。 如果是,則直接拋出異常。Spring 只能解決 單例模式的循環依賴,不能解決原型模式的循環依賴。
b. 當 BeanFactory 有 parentBeanFactory,并且 beanName 不在當前 beanDefinition 中 。 則通過 parentBeanFactory.getBean() 獲取 beanName 實例。
c. 標記正在創建 Bean 實例。
d. 獲取 合并后的 beanDefinition 定義信息,并檢查 beanDefinition 信息。
e. 從 beanDefinition 中獲取所有依賴 bean 信息。先創建依賴 Bean 的實例。
f. 如果是單例模式,則使用單例邏輯創建 Bean 實例。創建好后再通過 getObjectForBeanInstance 處理。
j. 如果是原型模式,則使用原型邏輯創建 Bean 實例。創建好后再通過 getObjectForBeanInstance 處理。
h. 如果其他自定義作用域模式,則使用對應的邏輯創建 Bean 實例。創建好后再通過 getObjectForBeanInstance 處理。
5.如果創建的 bean 實例 和 指定的類型不匹配,則轉換成指定的類型。
1 /** 2 * Return an instance, which may be shared or independent, of the specified bean. 3 * @param name the name of the bean to retrieve 4 * @param requiredType the required type of the bean to retrieve 5 * @param args arguments to use when creating a bean instance using explicit arguments 6 * (only applied when creating a new instance as opposed to retrieving an existing one) 7 * @param typeCheckOnly whether the instance is obtained for a type check, 8 * not for actual use 9 * @return an instance of the bean 10 * @throws BeansException if the bean could not be created 11 */ 12 @SuppressWarnings("unchecked") 13 protected <T> T doGetBean( 14 String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) 15 throws BeansException { 16 17 // 將 name 轉換成 BeanDefinition 中定義的信息。 18 // 1. 如果name 名稱前面有 &,則循環去掉。 & 表示FactoryBean 19 // 2. 如果name 是別名的話,則循環轉換成 BeanDefinition 中定義的 id 名稱。 20 String beanName = transformedBeanName(name); 21 Object beanInstance; 22 23 // singletonFactories earlySingletonObjects singletonObjects 24 // 1.檢查 singletonObjects 或 earlySingletonObjects 中是否有在創建的 對象實例信息。 25 // 2. 添加同步鎖, 重新校驗(雙重校驗 ) singletonObjects 或 earlySingletonObjects 是否有 對象實例信息。 26 // 3. 獲取 singletonFactories 中對象實例信息。如果獲取到,放到 earlySingletonObjects 中。 27 // 4. 否在返回 null 對象。 28 29 // Eagerly check singleton cache for manually registered singletons. 30 Object sharedInstance = getSingleton(beanName); 31 if (sharedInstance != null && args == null) { 32 if (logger.isTraceEnabled()) { 33 if (isSingletonCurrentlyInCreation(beanName)) { 34 logger.trace("Returning eagerly cached instance of singleton bean '" + beanName + 35 "' that is not fully initialized yet - a consequence of a circular reference"); 36 } 37 else { 38 logger.trace("Returning cached instance of singleton bean '" + beanName + "'"); 39 } 40 } 41 beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null); 42 } 43 44 else { 45 // Fail if we're already creating this bean instance: 46 // We're assumably within a circular reference. 47 if (isPrototypeCurrentlyInCreation(beanName)) { 48 throw new BeanCurrentlyInCreationException(beanName); 49 } 50 51 // Check if bean definition exists in this factory. 52 BeanFactory parentBeanFactory = getParentBeanFactory(); 53 if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { 54 // Not found -> check parent. 55 String nameToLookup = originalBeanName(name); 56 if (parentBeanFactory instanceof AbstractBeanFactory) { 57 return ((AbstractBeanFactory) parentBeanFactory).doGetBean( 58 nameToLookup, requiredType, args, typeCheckOnly); 59 } 60 else if (args != null) { 61 // Delegation to parent with explicit args. 62 return (T) parentBeanFactory.getBean(nameToLookup, args); 63 } 64 else if (requiredType != null) { 65 // No args -> delegate to standard getBean method. 66 return parentBeanFactory.getBean(nameToLookup, requiredType); 67 } 68 else { 69 return (T) parentBeanFactory.getBean(nameToLookup); 70 } 71 } 72 73 if (!typeCheckOnly) { 74 markBeanAsCreated(beanName); 75 } 76 77 StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate") 78 .tag("beanName", name); 79 try { 80 if (requiredType != null) { 81 beanCreation.tag("beanType", requiredType::toString); 82 } 83 RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); 84 checkMergedBeanDefinition(mbd, beanName, args); 85 86 // Guarantee initialization of beans that the current bean depends on. 87 String[] dependsOn = mbd.getDependsOn(); 88 if (dependsOn != null) { 89 for (String dep : dependsOn) { 90 if (isDependent(beanName, dep)) { 91 throw new BeanCreationException(mbd.getResourceDescription(), beanName, 92 "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'"); 93 } 94 registerDependentBean(dep, beanName); 95 try { 96 getBean(dep); 97 } 98 catch (NoSuchBeanDefinitionException ex) { 99 throw new BeanCreationException(mbd.getResourceDescription(), beanName, 100 "'" + beanName + "' depends on missing bean '" + dep + "'", ex); 101 } 102 } 103 } 104 105 // Create bean instance. 106 if (mbd.isSingleton()) { 107 sharedInstance = getSingleton(beanName, () -> { 108 try { 109 return createBean(beanName, mbd, args); 110 } 111 catch (BeansException ex) { 112 // Explicitly remove instance from singleton cache: It might have been put there 113 // eagerly by the creation process, to allow for circular reference resolution. 114 // Also remove any beans that received a temporary reference to the bean. 115 destroySingleton(beanName); 116 throw ex; 117 } 118 }); 119 beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); 120 } 121 122 else if (mbd.isPrototype()) { 123 // It's a prototype -> create a new instance. 124 Object prototypeInstance = null; 125 try { 126 beforePrototypeCreation(beanName); 127 prototypeInstance = createBean(beanName, mbd, args); 128 } 129 finally { 130 afterPrototypeCreation(beanName); 131 } 132 beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); 133 } 134 135 else { 136 String scopeName = mbd.getScope(); 137 if (!StringUtils.hasLength(scopeName)) { 138 throw new IllegalStateException("No scope name defined for bean ′" + beanName + "'"); 139 } 140 Scope scope = this.scopes.get(scopeName); 141 if (scope == null) { 142 throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'"); 143 } 144 try { 145 Object scopedInstance = scope.get(beanName, () -> { 146 beforePrototypeCreation(beanName); 147 try { 148 return createBean(beanName, mbd, args); 149 } 150 finally { 151 afterPrototypeCreation(beanName); 152 } 153 }); 154 beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); 155 } 156 catch (IllegalStateException ex) { 157 throw new ScopeNotActiveException(beanName, scopeName, ex); 158 } 159 } 160 } 161 catch (BeansException ex) { 162 beanCreation.tag("exception", ex.getClass().toString()); 163 beanCreation.tag("message", String.valueOf(ex.getMessage())); 164 cleanupAfterBeanCreationFailure(beanName); 165 throw ex; 166 } 167 finally { 168 beanCreation.end(); 169 } 170 } 171 172 return adaptBeanInstance(name, beanInstance, requiredType); 173 }
三. BeanFactory 創建 Bean 實例
AbstractBeanFactory#getBean(java.lang.String)
--> AbstractBeanFactory#doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
--> AbstractAutowireCapableBeanFactory#createBean(String, RootBeanDefinition, Object[])
1. 解析 BeanClass 得到 對應的Class 實例,并設置到 BeanDefinition 上。
2. 準備覆蓋方法。
3. 通過 InstantiationAwareBeanPostProcessor 實現類創建 Bean 對象的實例。如果創建成功,則直接返回。
例如: org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator 實現類實現動態代理。
4. 在 3步驟沒有創建,則使用 AbstractAutowireCapableBeanFactory#doCreateBean() 創建對象實例 ,并返回。
1 /** 2 * Central method of this class: creates a bean instance, 3 * populates the bean instance, applies post-processors, etc. 4 * @see #doCreateBean 5 */ 6 @Override 7 protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) 8 throws BeanCreationException { 9 10 if (logger.isTraceEnabled()) { 11 logger.trace("Creating instance of bean '" + beanName + "'"); 12 } 13 RootBeanDefinition mbdToUse = mbd; 14 15 // Make sure bean class is actually resolved at this point, and 16 // clone the bean definition in case of a dynamically resolved Class 17 // which cannot be stored in the shared merged bean definition. 18 Class<?> resolvedClass = resolveBeanClass(mbd, beanName); 19 if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { 20 mbdToUse = new RootBeanDefinition(mbd); 21 mbdToUse.setBeanClass(resolvedClass); 22 } 23 24 // Prepare method overrides. 25 try { 26 mbdToUse.prepareMethodOverrides(); 27 } 28 catch (BeanDefinitionValidationException ex) { 29 throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), 30 beanName, "Validation of method overrides failed", ex); 31 } 32 33 try { 34 // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance. 35 Object bean = resolveBeforeInstantiation(beanName, mbdToUse); 36 if (bean != null) { 37 return bean; 38 } 39 } 40 catch (Throwable ex) { 41 throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, 42 "BeanPostProcessor before instantiation of bean failed", ex); 43 } 44 45 try { 46 Object beanInstance = doCreateBean(beanName, mbdToUse, args); 47 if (logger.isTraceEnabled()) { 48 logger.trace("Finished creating instance of bean '" + beanName + "'"); 49 } 50 return beanInstance; 51 } 52 catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) { 53 // A previously detected exception with proper bean creation context already, 54 // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry. 55 throw ex; 56 } 57 catch (Throwable ex) { 58 throw new BeanCreationException( 59 mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex); 60 } 61 }
四. AbstractAutowireCapableBeanFactory 創建 Bean 實例
AbstractBeanFactory#getBean(java.lang.String)
--> AbstractBeanFactory#doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
--> AbstractAutowireCapableBeanFactory#createBean(String, RootBeanDefinition, Object[])
--> AbstractAutowireCapableBeanFactory#doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
1. 創建 BeanWrapper 實例。
2. 通過 MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition() 實現類合并處理 BeanDefinition 配置。
3. 檢查 正在創建的 Bean 實例是否是 循環依賴 創建的單例。如果是循環依賴創建的單例,則添加 循環依賴的緩存信息。
即:將 ObjectFactory 實例保存到 singletonFactories 中。
4. 填充Bean 屬性信息。例如 Autowired注解屬性注入。
InstantiationAwareBeanPostProcessor#postProcessProperties 和 InstantiationAwareBeanPostProcessor#postProcessPropertyValues 相關處理。
5. 初始化 Bean 實例 。
a. 執行 實現Aware接口的相關方法。
b. 循環調用 BeanPostProcessor#postProcessBeforeInitialization() 方法。
c. 執行 init-method() 方法。
d. 循環調用 BeanPostProcessor#postProcessAfterInitialization() 方法。
6. 如果是單例創建,進行相關的特殊處理。
7. 注冊 Bean 的 銷毀相關邏輯處理方法。
8. 返回最終的 Bean 實例。可能是動態代理實例。
如下是幾個主要的方法,對應 Bean 創建的幾個生命周期。
-->> AbstractAutowireCapableBeanFactory#createBeanInstance()
-->> AbstractAutowireCapableBeanFactory#populateBean()
-->> AbstractAutowireCapableBeanFactory#initializeBean()
-->> AbstractAutowireCapableBeanFactory#invokeAwareMethods
-->> AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization
-->> AbstractAutowireCapableBeanFactory#invokeInitMethods
org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
AbstractAutowireCapableBeanFactory#invokeCustomInitMethod()
-->> AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization()
1 /** 2 * Actually create the specified bean. Pre-creation processing has already happened 3 * at this point, e.g. checking {@code postProcessBeforeInstantiation} callbacks. 4 * <p>Differentiates between default bean instantiation, use of a 5 * factory method, and autowiring a constructor. 6 * @param beanName the name of the bean 7 * @param mbd the merged bean definition for the bean 8 * @param args explicit arguments to use for constructor or factory method invocation 9 * @return a new instance of the bean 10 * @throws BeanCreationException if the bean could not be created 11 * @see #instantiateBean 12 * @see #instantiateUsingFactoryMethod 13 * @see #autowireConstructor 14 */ 15 protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) 16 throws BeanCreationException { 17 18 // Instantiate the bean. 19 BeanWrapper instanceWrapper = null; 20 if (mbd.isSingleton()) { 21 instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); 22 } 23 if (instanceWrapper == null) { 24 instanceWrapper = createBeanInstance(beanName, mbd, args); 25 } 26 Object bean = instanceWrapper.getWrappedInstance(); 27 Class<?> beanType = instanceWrapper.getWrappedClass(); 28 if (beanType != NullBean.class) { 29 mbd.resolvedTargetType = beanType; 30 } 31 32 // Allow post-processors to modify the merged bean definition. 33 synchronized (mbd.postProcessingLock) { 34 if (!mbd.postProcessed) { 35 try { 36 applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); 37 } 38 catch (Throwable ex) { 39 throw new BeanCreationException(mbd.getResourceDescription(), beanName, 40 "Post-processing of merged bean definition failed", ex); 41 } 42 mbd.postProcessed = true; 43 } 44 } 45 46 // Eagerly cache singletons to be able to resolve circular references 47 // even when triggered by lifecycle interfaces like BeanFactoryAware. 48 boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && 49 isSingletonCurrentlyInCreation(beanName)); 50 if (earlySingletonExposure) { 51 if (logger.isTraceEnabled()) { 52 logger.trace("Eagerly caching bean '" + beanName + 53 "' to allow for resolving potential circular references"); 54 } 55 addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); 56 } 57 58 // Initialize the bean instance. 59 Object exposedObject = bean; 60 try { 61 populateBean(beanName, mbd, instanceWrapper); 62 exposedObject = initializeBean(beanName, exposedObject, mbd); 63 } 64 catch (Throwable ex) { 65 if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) { 66 throw (BeanCreationException) ex; 67 } 68 else { 69 throw new BeanCreationException( 70 mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex); 71 } 72 } 73 74 if (earlySingletonExposure) { 75 Object earlySingletonReference = getSingleton(beanName, false); 76 if (earlySingletonReference != null) { 77 if (exposedObject == bean) { 78 exposedObject = earlySingletonReference; 79 } 80 else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { 81 String[] dependentBeans = getDependentBeans(beanName); 82 Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length); 83 for (String dependentBean : dependentBeans) { 84 if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { 85 actualDependentBeans.add(dependentBean); 86 } 87 } 88 if (!actualDependentBeans.isEmpty()) { 89 throw new BeanCurrentlyInCreationException(beanName, 90 "Bean with name '" + beanName + "' has been injected into other beans [" + 91 StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + 92 "] in its raw version as part of a circular reference, but has eventually been " + 93 "wrapped. This means that said other beans do not use the final version of the " + 94 "bean. This is often the result of over-eager type matching - consider using " + 95 "'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example."); 96 } 97 } 98 } 99 } 100 101 // Register bean as disposable. 102 try { 103 registerDisposableBeanIfNecessary(beanName, bean, mbd); 104 } 105 catch (BeanDefinitionValidationException ex) { 106 throw new BeanCreationException( 107 mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); 108 } 109 110 return exposedObject; 111 }
五. 循環依賴的處理
spring 只解決了 單例模式的 循環依賴問題。原型模式,構造器注入的等循環依賴沒用解決。
AbstractAutowireCapableBeanFactory#doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
AbstractAutowireCapableBeanFactory#createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
DefaultSingletonBeanRegistry#addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory)
AbstractAutowireCapableBeanFactory#populateBean()
AbstractAutowireCapableBeanFactory#initializeBean()
1. 在創建A bean 原生實例后,將 ObjectFactory 包裝后的實例 存入 singletonFactories (三級緩存 DefaultSingletonBeanRegistry#singletonFactories)中。
2. 填充A bean 屬性。這個時候可能會遇到 循環依賴問題。當填充其他 bean 實例時,其他bean又 依賴A bean 時,獲取A bean實例時,先從 singletonFactories 獲取的 ObjectFactory 實例,調用ObjectFactory#getObject() 獲取處理后的 A bean 實例(最終調用AbstractAutowireCapableBeanFactory#getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean)方法依次調用
SmartInstantiationAwareBeanPostProcessor#getEarlyBeanReference(Object bean, String beanName) 方法。
),并存入 earlySingletonObjects (二級緩存 DefaultSingletonBeanRegistry#earlySingletonObjects)
3. 初始化bean 處理。AbstractAutowireCapableBeanFactory#initializeBean()
4. 當是單例 bean 創建時,獲得 earlySingletonObjects (二級緩存 DefaultSingletonBeanRegistry#earlySingletonObjects) 保存的 bean處理后的實例 earlySingletonReference。
5. 當 earlySingletonReference 不為null,并且 exposedObject == bean 時,則使用 earlySingletonReference 代替A bean 原生實例。
/** * Actually create the specified bean. Pre-creation processing has already happened * at this point, e.g. checking {@code postProcessBeforeInstantiation} callbacks. * <p>Differentiates between default bean instantiation, use of a * factory method, and autowiring a constructor. * @param beanName the name of the bean * @param mbd the merged bean definition for the bean * @param args explicit arguments to use for constructor or factory method invocation * @return a new instance of the bean * @throws BeanCreationException if the bean could not be created * @see #instantiateBean * @see #instantiateUsingFactoryMethod * @see #autowireConstructor */ protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { // Instantiate the bean. BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { instanceWrapper = createBeanInstance(beanName, mbd, args); } Object bean = instanceWrapper.getWrappedInstance(); Class<?> beanType = instanceWrapper.getWrappedClass(); if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; } // Allow post-processors to modify the merged bean definition. 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. boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName)); if (earlySingletonExposure) { if (logger.isTraceEnabled()) { logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references"); } addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); } // Initialize the bean instance. Object exposedObject = bean; try { populateBean(beanName, mbd, instanceWrapper); 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) { Object earlySingletonReference = getSingleton(beanName, false); if (earlySingletonReference != null) { if (exposedObject == bean) { exposedObject = earlySingletonReference; } else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { String[] dependentBeans = getDependentBeans(beanName); Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length); for (String dependentBean : dependentBeans) { 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 " + "'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example."); } } } } // Register bean as disposable. try { registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject; }
在創建 bean 時,如果一直操作的是A bean 原生實例。單例循環依賴正常解決。當遇到經過一系列處理后返回的非A bean 原生實例時,默認則會報錯,需要繼承 SmartInstantiationAwareBeanPostProcessor接口,實現 getEarlyBeanReference() 方法。當是動態代理,返回的是AbstractAutoProxyCreator#getEarlyBeanReference(Object bean, String beanName) 處理后的 A bean 代理對象。
六: BEAN 生命周期
在創建 Bean 對象實例時,通過各個生命周期,進行BEAN功能擴展
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean()
-> org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance(beanName, mbd, args)
-> org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean(beanName, mbd, instanceWrapper)
-> org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(beanName, exposedObject, mbd)
-> org.springframework.beans.factory.support.AbstractBeanFactory#registerDisposableBeanIfNecessary(beanName, bean, mbd)
0. org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation()
在創建 bean 實例 之前,先通過檢查是否通過處理器 InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation() 創建實例。如果創建實例了,則直接返回,后續步驟不執行。
1. createBeanInstance() 通過 bean 構造函數創建實例。
2. populateBean() 給創建好的 bean 實例填充字段數據。
①. 先檢查是否執行 bean 實例化后增強處理方法 org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation 。如果執行了,則直接返回,后續步驟不執行。
②. 填充 @Autowired ,@Resource 修飾的字段值。 或 setter 方法處理的字段。
3. initializeBean() bean 初始化,并進行增強處理(包含AOP處理)。
①. 當 Bean 對象實現了 BeanNameAware,BeanClassLoaderAware,BeanFactoryAware 接口時,則調用對應的set方法,設置對應的信息。
②. 進行 bean 初始化前的增強處理 org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization().
③. 調用 bean 的初始化 方法。
當 bean 實現了 InitializingBean 接口時,執行 InitializingBean#afterPropertiesSet() 方法。
當 bean 配置了 初始化方法(initMethod) 方法時,通過反射調用配置的初始化方法。
初始化方法配置方式一:
通過bean節點init-method 屬性配置。 <bean id="beanName" class="BeanTypeName" init-method="init" destroy-method="destroy">
方式二: 通過 @Bean(initMethod = "init", destroyMethod = "destroy") 配置。
方式三: 通過 @PostConstruct 標記初始化方法。
④. 進行 bean 初始化后的增強處理 org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization() .士大夫
4. AbstractBeanFactory#registerDisposableBeanIfNecessary 注冊銷毀 bean 時的處理。 具體通過 DisposableBeanAdapter#destroy() 實現處理。
① 進行 bean 銷毀前的增強處理 DestructionAwareBeanPostProcessor#postProcessBeforeDestruction()。
② 如果 bean 實現了 DisposableBean 接口,則調用 銷毀方法 bean#destroy() 。
③ 調用配置的銷毀方法
銷毀方法配置方式一:
通過bean節點 destroy-method 屬性配置。 <bean id="beanName" class="BeanTypeName" init-method="init" destroy-method="destroy">
當配置 <bean destroy-method=""> or <beans default-destroy-method=""> 時,則尋找 close 或 shutdown 方法名。
方式二: 通過 @Bean(initMethod = "init", destroyMethod = "destroy") 配置。
方式三: 通過 @PreDestroy 標記的銷毀方法。
如果覺得這篇文章對你有小小的幫助的話,記得在右下角點個“推薦”哦,博主在此感謝!
浙公網安備 33010602011771號