11、解释一下 spring bean 的生命周期
12、解释 Spring 支持的几种 bean 的作用域?
本期分享到此为止,关注博主不迷路,叶秋学长带你上高速~~
首先说一下 Servlet 的生命周期:实例化,初始 init,接收请求 service,销毁 destroy;
Spring 上下文中的 Bean 生命周期也类似,如下:
(1)实例化 Bean:
对于 BeanFactory 容器,当客户向容器请求一个尚未初始化的 bean 时,或初始化 bean 的时候需要注入另一个尚未初始化的依赖时,容器就会调用 createBean 进行实例化。对于 ApplicationContext 容器,当容器启动结束后,通过获取 BeanDefinition 对象中的信息,实例化所有的 bean。
(2)设置对象属性(依赖注入):
实例化后的对象被封装在 BeanWrapper 对象中,紧接着,Spring 根据 BeanDefinition 中的信息 以及 通过 BeanWrapper 提供的设置属性的接口完成依赖注入。
(3)处理 Aware 接口:
接着,Spring 会检测该对象是否实现了 xxxAware 接口,并将相关的 xxxAware 实例注入给 Bean:
①如果这个 Bean 已经实现了 BeanNameAware 接口,会调用它实现的 setBeanName(StringbeanId)方法,此处传递的就是 Spring 配置文件中 Bean 的 id 值;
②如果这个 Bean 已经实现了 BeanFactoryAware 接口,会调用它实现的 setBeanFactory()方法,传递的是 Spring 工厂自身。
③如果这个 Bean 已经实现了 ApplicationContextAware 接口,会调用
setApplicationContext(ApplicationContext)方法,传入 Spring 上下文;
(4)BeanPostProcessor:
如果想对 Bean 进行一些自定义的处理,那么可以让 Bean 实现了 BeanPostProcessor 接口,那将会调用 postProcessBeforeInitialization(Object obj, String s)方法。
(5)InitializingBean 与 init-method:
如果 Bean 在 Spring 配置文件中配置了 init-method 属性,则会自动调用其配置的初始化方法。
(6)如果这个 Bean 实现了 BeanPostProcessor 接口,将会调用
postProcessAfterInitialization(Object obj, String s)方法;由于这个方法是在 Bean 初始化结束时调用的,所以可以被应用于内存或缓存技术;
以上几个步骤完成后,Bean 就已经被正确创建了,之后就可以使用这个 Bean 了。
(7)DisposableBean:
当 Bean 不再需要时,会经过清理阶段,如果 Bean 实现了 DisposableBean 这个接口,会调用其实现的 destroy()方法;
(8)destroy-method:
最后,如果这个 Bean 的 Spring 配置中配置了 destroy-method 属性,会自动调用其配置的销毁方法。
Spring 容器中的 bean 可以分为 5 个范围:
(1)singleton:默认,每个容器中只有一个 bean 的实例,单例的模式由 BeanFactory 自身来维护。
(2)prototype:为每一个 bean 请求提供一个实例。
(3)request:为每一个网络请求创建一个实例,在请求完成以后,bean 会失效并被垃圾回收器回收。
(4)session:与 request 范围类似,确保每个 session 中有一个 bean 的实例,在 session 过期后,
bean 会随之失效。
(5)global-session:全局作用域,global-session 和 Portlet 应用相关。当你的应用部署在 Portlet
容器中工作时,它包含很多 portlet。如果你想要声明让所有的 portlet 共用全局的存储变量的话,那么这全局变量需要存储在 global-session 中。全局作用域与 Servlet 中的 session 作用域效果相同。