前言

在面试的时候,对应Spring的内容是必面的知识点之一,Spring的整个体系还是比较庞大的,对于其深度和广度的深入了解也是高级开发必须掌握的知识点,Spring的源码架构及实现逻辑也是架构师必须了解的内容,如本次问题中Spring中bean的生命周期的理解,其实考察的就是你对Spring是否熟悉,这部分内容工作中几乎很少用到。

正文

在Spring中,BeanFactory或ApplicationContext可以加载XML取得bean实例。对于XML中加载得到的bean对象默认加载范围为singleton,即每一个别名在容器中只能维持一个实例,而不是每次都产生一个新的对象。

这里涉及到另一个问题,也就是Spring下的单例bean并不是线程安全的。

那么,怎么避免这个问题呢?解决思路就是每次getBean的时候都让产生一个新的实例。

对于bean的作用域spring为我们提供了如下几种:singleton、prototype、request、session、globalsession。

如果是线程安全,可以将bean的作用域设置为prototype,即每次从容器中调用Bean时,都返回一个实例。

对于bean的声明周期:

一、如果使用BeanFactory来生成,管理Bean的话,会经历如下几个步骤:

图片

根据上如详细步骤为:

1:Bean的建立:

容器寻找Bean的定义信息并将其实例化。

2:属性注入:

使用依赖注入,Spring按照Bean定义信息配置Bean所有属性

3:BeanNameAware的setBeanName():

如果Bean类有实现org.springframework.beans.BeanNameAware接口,工厂调用Bean的setBeanName()方法传递Bean的ID。

4:BeanFactoryAware的setBeanFactory():

如果Bean类有实现org.springframework.beans.factory.BeanFactoryAware接口,工厂调用setBeanFactory()方法传入工厂自身。

5:BeanPostProcessors的ProcessBeforeInitialization()

如果有org.springframework.beans.factory.config.BeanPostProcessors和Bean关联,那么其postProcessBeforeInitialization()方法将被将被调用。

6:initializingBean的afterPropertiesSet():

如果Bean类已实现org.springframework.beans.factory.InitializingBean接口,则执行他的afterProPertiesSet()方法

7:Bean定义文件中定义init-method:

可以在Bean定义文件中使用"init-method"属性设定方法名称例如:

<bean id="demoBean" class="com.yangsq.bean.DemoBean" init-method="initMethod">

.......

</bean>

如果有以上设置的话,则执行到这个阶段,就会执行initMethod()方法

8:BeanPostProcessors的ProcessaAfterInitialization()

如果有任何的BeanPostProcessors实例与Bean实例关联,则执行BeanPostProcessors实例的ProcessaAfterInitialization()方法

此时,Bean已经可以被应用系统使用,并且将保留在BeanFactory中知道它不在被使用。有两种方法可以将其从BeanFactory中删除掉。

8.1:DisposableBean的destroy()

在容器关闭时,如果Bean类有实现org.springframework.beans.factory.DisposableBean接口,则执行他的destroy()方法

8.2:Bean定义文件中定义destroy-method

在容器关闭时,可以在Bean定义文件中使用"destroy-method"属性设定方法名称

<bean id="demoBean" class="com.yangsq.bean.DemoBean" destory-method="destroyMethod">

.......

</bean>

这时会执行destroyMethod()方法,注意,这个方法是不带参数的。

二、使用ApplicationContext来生成,管理Bean。

和上面使用BeanFactory稍有不同的是在执行BeanFactoryAware的setBeanFactory()阶段后,若Bean类上有实现org.springframework.context.ApplicationContextAware接口,则执行其setApplicationContext()方法,接着才执行BeanPostProcessors的ProcessBeforeInitialization()及之后的流程。

另附,Spring中部分关键类关联图结构:

图片

Spring的bean的声明周期全部内容

以上。