Spring中bean的实例化的总的入口都是getBean方法
具体的实现是在AbstractBeanFactory中。
1.bean实例化的总体逻辑
getBean->doGetBean,最终的逻辑是在doGetBean中
doGetBean的大体逻辑归纳如下:
转换bean名字
if(原生bean实例已经实例化){
判断该bean是否是FactoryBean,若是,则获取FactoryBean创建的bean。若FactoryBean是单例,则将创建的bean缓存起来。
}else{
if(bean存在于父容器中){
从父容器中获取bean实例
}else{
获取bean的定义信息BeanDefinition
先实例化依赖的bean
if(bean配置为单例){
先创建bean的实例
然后判断bean是否是FactoryBean,若是,则获取FactoryBean创建的bean,若FactoryBean是单例,则将创建的bean缓存起来。
}else if(bean配置为原型){
实例化bean的前置准备(默认实现中,是把当前beanName加入到prototypesCurrentlyInCreation集合中,用于检查循环依赖的问题)
创建bean的实例
实例化的后置操作(默认实现中,是把当前beanName从prototypesCurrentlyInCreation集合中删除。)
然后判断bean是否是FactoryBean,若是,则获取FactoryBean创建的bean,若FactoryBean是单例,则将创建的bean缓存起来。
}else{
获取bean的scope
采用原型bean创建的过程创建bean实例
将bean加入到scope中
然后判断bean是否是FactoryBean,若是,则获取FactoryBean创建的bean,若FactoryBean是单例,则将创建的bean缓存起来。
}
}
检查bean的类型与传入参数指定类型是否一致根据上面的逻辑可以看出,bean的实例化过程中主要是按照三种scope域进行实例化。
下面根据上面的大体逻辑把getBean分成以下几段独立逻辑分别分析。
2. 各独立逻辑模块功能分析
2.1 bean名字转换
final String beanName = transformedBeanName(name);bean名字转换:
1.首先去除FactoryBean对应的name的前缀。这里FacotryBean实例的前缀为&,应该注意的是,FacotryBean自身是可以嵌套的,即某个FactoryBean可以由其他FactoryBean创建。
2.然后若name为别名,则获取别名对应的正真的beanName。别名的管理由SimpleAliasRegistry负责,其中提供了一个aliasMap,存储的结构为[alias,beanName]
2.2 从单例缓存中获取已经实例化的bean
1. getSingleton(),从缓存singletonObjects中获取已经实例化的bean,如果bean已经被实例化,则执行下面的逻辑:
if (sharedInstance != null && args == null) {
if (logger.isDebugEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
}
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}2. 上面这段代码的主要逻辑是在getObjectForBeanInstance中,这个方法也是每个bean在实例化都会执行的一段逻辑,该方法的大体逻辑是:判断传入的bean实例是否是FactoryBean,若不是,则直接返回该实例,否则则用FactroyBean创建对应bean的实例。在后面会讲到FactoryBean实际上就是AOP和IOC容器的一个接入点。 getObjectForBeanInstance中FactoryBean处理的部分代码:
Object object = null;
if (mbd == null) {
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// Return bean instance from factory.
FactoryBean factory = (FactoryBean) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;这里, 1.首先尝试获取缓存的中已经被FactoryBean创建好的bean实例.
2.若没有,则判断beanName指定的配置是否在Spring容器中存在,存在则则获取merge后的BeanDefinition。这里的synthetic实际上是为了给用户自定义一些BeanDefinition注册到容器中以当作工具类来使用。对于synthetic类型的BeanDefinition,getObjectFromFactoryBean中是不会对FactoryBean生成的bean用post-processor进行后置处理的。后置处理的实现是在AbstractAutowireCapableBeanFactory.postProcessObjectFromFactoryBean中,它会调用容器中的BeanPostProcessor.postProcessAfterInitialization,这里提供了一个扩展点对FactoryBean生成的bean进行封装,代理等。
3.由FactoryBean创建的单例bean,spring会把它缓存起来,用于下次直接从缓存中获取。
2.3 从父容器中获取bean实例
若从当前容器中取不到已经被实例化的bean,判断bean是否在父容器中定义,若在,则从父容器中取得实例。
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
String nameToLookup = originalBeanName(name);
if (args != null) {
// Delegation to parent with explicit args.
return parentBeanFactory.getBean(nameToLookup, args);
}
else {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}1. isPrototypeCurrentlyInCreation方法是用于循环依赖检测,spring在实例化prototype类型的bean之前,会把bean的名字加入到“正在创建的缓存”中,若bean1在创建过程依赖bean2,而bean2创建过程中同时又依赖bean1,则直接抛出异常。 在当前容器做实例化之前,会先判断bean是否由父容器来创建。若是,说明只能在父容器中找了。先还原bean的名字,然后调用父容器的getBean方法,可见,这里也是递归的过程。
这里需要注意的是,若当前容器中定义了一个名为bean1的bean,而父容器也定义了一个同名bean,这时还是会优先实例化当前容器的同名bean
2.4 实例化前的准备
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (int i = 0; i < dependsOn.length; i++) {
String dependsOnBean = dependsOn[i];
getBean(dependsOnBean);
registerDependentBean(dependsOnBean, beanName);
}
}这里是三类scope实例化前共有的逻辑。 1.首先,对正在进行创建的bean进行标记。
2.获取bean的merge之后的BeanDefinition
3.检查当前bean的依赖的bean,先实例化,并保存beanName依赖的bean的名字,用于在destory时能够按照顺序销毁。
2.5 实例化单例bean
if(mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, new ObjectFactory() {
public Object getObject() throws BeansException {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}1.getSingleton()是一个包含回调接口的方法,定义了创建原生bean实例的模板过程,正在的实例化bean的逻辑由外部传入的ObjectFactory接口实现。 getSingleton()模板方法中,定义了几个扩展接口beforeSingletonCreation和afterSingletonCreation,用于在实例化前后做相应的处理,在获得实例后通过addSingleton将singleton缓存起来。
getSingleton()的大致逻辑归纳如下:
基本结构
beforeSingletonCreation()
try{
objectFactory.getObject();
}catch(Exception e){
}finally{
afterSingletonCreation
}
addSingleton();真正的创建过程的过程在AbstractAutowireCapableBeanFactory.createBean方法中。createBean方法中会产生bean实例,具体过程后面深入分析。容器中除了FacotryBean产生的bean不是采用createBean实例化,其他bean最终的实例化都会是通过createBean来创建。
2.getObjectForBeanInstance的具体逻辑在前面已经分析,主要是对FactoryBean进行特殊处理。
2.6 实例化原型bean
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}原型实例化的过程实际上与单例实例化的过程类似, a.beforePrototypeCreation把beanName加入到ThreadLocal中,可以用于避免线程重复创建该bean。
b.createBean(),与单例bean同一个执行逻辑
c.afterPrototypeCreation()清除threadLocal中的标志。
2.7 根据scope域实例化bean
如果没有指定,则从scope中创建beanString scopeName = mbd.getScope();
final Scope scope = (Scope) this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, new ObjectFactory() {
public Object getObject() throws BeansException {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}finally {
afterPrototypeCreation(beanName);
}
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; " +
"consider defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}如果没有指定,则从scope中创建bean。 这里也是采用回调的方式,创建的原生的bean实际调用的是创建原型bean的逻辑。创建逻辑还是在createBean中。
在spring.web中AbstractRequestAttributesScope定义了get方法过程,当然我们也可以自己定义一个Scope。
public Object get(String name, ObjectFactory objectFactory) {
RequestAttributes attributes = RequestContextHolder.currentRequestAttributes();
Object scopedObject = attributes.getAttribute(name, getScope());
if (scopedObject == null) {
scopedObject = objectFactory.getObject();
attributes.setAttribute(name, scopedObject, getScope());
}
return scopedObject;
}如果request中已经缓存了实例,直接返回,否则利用objectFactory创建bean实例,并且保存到attribute中。2.8 创建bean
2.8.1 createBean
createBean的默认实现是在AbstractAutowireCapableBeanFactory中
resolveBeanClass(mbd, beanName);
// Prepare method overrides.
try {
mbd.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbd.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbd);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
Object beanInstance = doCreateBean(beanName, mbd, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;1. resolveBeanClass()加载bean指定的class. 2. mbd.prepareMethodOverrides() 对当前bean中方法替换的设置进行验证和优化(如果一个方法覆盖器MethodOverrides只覆盖了一个方法,就通过设置重载overloaded为false来避免参数及返回值类型检查)
在spring支持两种方式的方法覆盖
一种是lookup方式,这种方式只能对不带任何参数的方法才能覆盖。
<bean id="commandManager" class="fiona.apple.CommandManager">
<lookup-method name="createCommand" bean="command"/>
</bean>另一种是replace-method方式,但是需要实现MethodReplacer接口<bean id="replacementTarget"
class="ReplacementTarget" >
<replace-method name="formatMessage" replacer="methodReplacer">
<arg-type>String</arg-type>
</replace-method>
</bean>3. resolveBeforeInstantiation()调用InstantiationAwareBeanPostProcessor接口的postProcessBeforeInstantiation方法处理,扩展点,用于返回bean的代理对象,干涉bean的实例化。从代码中可以看到,resolveBeforeInstantiation如果创建了bean,则直接返回该实例。 4. doCreateBean 创建原生bean实例。
2.8.2 doCreateBean
doCreateBean方法的逻辑主要可以分为以下几部分
1. 创建BeanWrapper及创建后的后置处理
2. 属性注入
3. bean实例初始化
4. 对于非protype类型的bean,注册bean销毁的回调接口
1. 创建BeanWrapper及创建后的后置处理
2. 属性注入
3. bean实例初始化
4. 对于非protype类型的bean,注册bean销毁的回调接口
第1部分:创建BeanWrapper及创建后的后置处理
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = (BeanWrapper) this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
Class beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
mbd.postProcessed = true;
}
}从代码中可以看到,实例化的过程中会采用BeanWrapper这样一个bean包装器对bean实例进行包装
BeanWrapper的类结构图如下:

从BeanWrapper的doc中我们可以清楚的看到这个类的主要功能:
BeanWrapper提供了设置和获取属性值(单个的或者是批量的),获取属性描述信息、查询只读或者可写属性等功能。不仅如此,BeanWrapper还支持嵌套属性,你可以不受嵌套深度限制对子属性的值进行设置。所以,BeanWrapper无需任何辅助代码就可以支持标准JavaBean的PropertyChangeListeners和VetoableChangeListeners。除此之外,BeanWrapper还提供了设置索引属性的支持。
createBeanInstance这个方法会根据三种情况来创建实例:
a. 若当前bean配置了factory-method,则采用factory-method来创建bean。
factory-method类型的bean实例,调用过程:
AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod() -> ConstructorResolver.instantiateUsingFactoryMethod()
instantiateUsingFactoryMethod()方法中代码的逻辑分为以下几块:
1. 准备BeanWrapperImpl实例
BeanWrapperImpl bw = new BeanWrapperImpl();
this.beanFactory.initBeanWrapper(bw);这里需要注意的是initBeanWrapper,该方法会拷贝一份容器中注册的PropertyEditor,用于属性类型转换。 2. 获取FactoryClass的Class对象,这里spring支持两种方式的factory-method配置方式
第一种方式--采用静态方法
<bean id="random"
class="example.StaticStudentFactory"
factory-method="createStudent" //createStudent方法必须是static的
scope="prototype"/>第二种方式:<bean id="instanceFactoryBean" class="example.InstanceFactoryBean">
<property name="format" value="yyyy-MM-dd HH:mm:ss" />
</bean>
<bean id="currentTime" factory-bean="instanceFactoryBean" factory-method="createTime"/>3. 得到factory-method中方法的参数值 一种是直接在getbean的时候传入
一种情况是根据配置文件中解析,解析的依据是根据返回的目标bean的构造方法需要的参数来判断的。
4. 根据factoryClass类型和传入参数,方法名称唯一确定工厂方法。
5.根据实例化策略,创建bean,这里实际上只是采用jdk的反射机制来调用factory-method方法。
6.将创建的实例放入beanWrapper实例中返回。
b. 若当前bean配置了<construct-arg>参数或者自动注入模式为AUTOWIRE_CONSTRUCTOR或者构造方法参数不为空,则通过指定的构造函数来创建bean。
对于配置了<construct-arg>参数的bean,的调用过程为:
AbstractAutowireCapableBeanFactory.autowireConstructor()->ConstructorResolver.autowireConstructor()
ConstructorResolver.autowireConstructor()
的逻辑与instantiateUsingFactoryMethod的逻辑基本一致
先准备BeanWrapperImpl实例,然后根据传入参数或者配置<construct-arg>参数确定唯一的构造函数,然后反射机制调用构造函数创建对象,并将构造函数缓存起来,避免下次再进行解析匹配。
在这里需要注意的是,对应设置了lookup或这replace-method的bean,在创建对象时默认会采用cglib来创建一个代理对象以此来实现方法替换的效果。
AbstractAutowireCapableBeanFactory.autowireConstructor()->ConstructorResolver.autowireConstructor()
ConstructorResolver.autowireConstructor()
的逻辑与instantiateUsingFactoryMethod的逻辑基本一致
先准备BeanWrapperImpl实例,然后根据传入参数或者配置<construct-arg>参数确定唯一的构造函数,然后反射机制调用构造函数创建对象,并将构造函数缓存起来,避免下次再进行解析匹配。
在这里需要注意的是,对应设置了lookup或这replace-method的bean,在创建对象时默认会采用cglib来创建一个代理对象以此来实现方法替换的效果。
c. 不是以上两种情况,则采用默认的无参构造函数来创建bean。
对于这类bean,创建对象的过程很简单,直接获取bean指定class中的无参构造方法,并实例化之。当然若设置了lookup或这replace-method,则创建一个当前类的代理对象。
第2部分:属性的注入
单例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, new ObjectFactory() {
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}从代码逻辑可以看出,这里会把beanName和一个对应的ObjectFactory对象增加到singletonFactories缓存中,分析getEarlyBeanReference可以知道,它会调用SmartInstantiationAwareBeanPostProcessor这个后置处理器的getEarlyBeanReference()方法,大多数情况下,实际上相当于直接返回已经实例化的bean的引用。 为何要这样?
主要是用于解决单例bean之间存在的循环依赖,
如何实现的呢?
回到AbstractBeanFacotry.doGetBean()方法的逻辑中,我们知道在创建bean之前会先去判断当前beanName对应的bean是否已经被实例化,具体实现是在:AbstractBeanFacotry.getSingleton()方法,这个方法会依次检查不同的缓存,
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
synchronized (this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory singletonFactory = (ObjectFactory) this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);这里就会去检查singletonFactories中是否已经有与beanName对应的ObjectFactory,有的话,直接返回由ObjectFactory创建的对象,这里也就是正在创建过程中的bean的引用。 举个例子:如 A->B->C->A,在A创建过程中属性注入时需要B,于是实例化B,在实例化B时又需要C,因此会去先实例化C,在C属性注入过程中发现需要A,因此通过getBean(A)来实例化A,此时,A已经将其实例的引用通过ObjectFactory的方式放到singletonFactories中缓存起来了,因此直接返回,于是C可以顺利实例化,B也可以顺利完成实例化,A在得到B的实例化,即可进行下面的实例化过程。
这里需要注意的是,spring中只能解决单例bean且为setter方式的循环依赖,对于原型bean或是单例bean构造函数方式的循环依赖,spring是无法解决的,只能抛出异常了(原型bean,在spring容器中不存在缓存。单例bean构造函数方式依赖时,由于bean没有构造好,无法取得实例bean的引用)。
属性的注入逻辑封装在populateBean方法中
这个方法的逻辑是:
a. 在属性注入之前,先调用InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation方法,该接口通过返回false能中断属性的注入过程。
b. 解析bean的依赖注入方式,获取属性的值,针对AUTOWIRE_BY_NAME和AUTOWIRE_BY_TYPE进行不同处理。
若为AUTOWIRE_BY_NAME,则针对beanclass中的复杂对象属性的名字,实例化容器中对应与属性名相同的bean,并保存起来,并注册到当前bean的依赖缓存列表中。
对于AUTOWIRE_BY_TYPE,解析规则相对而言要复杂很多。
c.调用InstantiationAwareBeanPostProcessor的postProcessPropertyValues方法,对属性值进行转换。这里主要的一个应用是对注解的解析如@Required注解进行支持。
d.检查bean的dependency-check参数,过滤掉dependency-check为DEPENDENCY_CHECK_NONE的属性。然后再调用InstantiationAwareBeanPostProcessor.postProcessPropertyValues方法。然后再对属性依赖进行检查。从实现来看,checkDependencies没干啥事,这个参数作用不大。
e.用得到属性值,注入到目标对象中.这个实现是在applyPropertyValues()方法中,
d.检查bean的dependency-check参数,过滤掉dependency-check为DEPENDENCY_CHECK_NONE的属性。然后再调用InstantiationAwareBeanPostProcessor.postProcessPropertyValues方法。然后再对属性依赖进行检查。从实现来看,checkDependencies没干啥事,这个参数作用不大。
e.用得到属性值,注入到目标对象中.这个实现是在applyPropertyValues()方法中,
applyPropertyValues()方法的大体逻辑是,通过前面解析的属性依赖实例化成具体值,具体包括ref,local和内部bean等bean依赖的实例化,以及List,Map,Set等特容器属性,然后将得到值采用TypeConvertor进行转换得到最终的属性值,最后通过BeanWrapper.setPropertyValues方法将得到的值注入到bean实例中。
第3部分 bean实例初始化
这个逻辑主要封装在initializeBean()方法中
具体代码
protected Object initializeBean(String beanName, Object bean, RootBeanDefinition mbd) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(this);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}代码逻辑很清楚包括以下几步1.BeanNameAware,BeanClassLoaderAware,BeanFactoryAware的三个Aware接口的注入
2.applyBeanPostProcessorsBeforeInitialization() 方法,在初始化方法调用之前调用BeanPostProcessor.postProcessBeforeInitialization()方法
3.调用initMethod方法,这里主要两类init,一类是实现了InitializingBean,如果实现了,则调用它的afterPropertiesSet()方法;另外,若在bean的定义中指定了init-method方法,则调用用户自定义的init-method。注:两类init方法都存在时,会先调用InitializingBean的方法。然后再调用init-method指定的方法。
4.applyBeanPostProcessorsAfterInitialization(),这在初始化方法调用之后,会调用BeanPostProcessor.postProcessAfterInitialization()方法
第4部分 对于非protype类型的bean,注册bean销毁的回调接口
这里的销毁接口按照单例 scope和其他scope(如request,Session)进行分别注册,单例scope由spring容器负责保存注册的回调接口,其他scope由scope负责管理。
销毁接口包括三类:
第一类是用户通过bean配置中指定destroy-method指定的销毁方法。
第二类是注册了DestructionAwareBeanPostProcessor这个Bean后置处理器,则在销毁时调用该DestructionAwareBeanPostProcessor.postProcessBeforeDestruction()
第三类是bean自身实现了DisposableBean接口,则在销毁时调用destroy方法
这三类方法的顺序为:
DestructionAwareBeanPostProcessor->DisposableBean->destroy-method
至此整个bean就已经实例化完毕。
版权声明:本文为shuangyue原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。