业务系统通过直接或间接调用 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 }View Code
二. 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 }View Code
三. 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 }View Code
四. 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[])
--> 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#invokeAwareMethods
-->> AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization
-->> AbstractAutowireCapableBeanFactory#invokeInitMethods
org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
-->> 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 }View Code