Spring Bean 生命周期比较复杂,可以简单分为创建和销毁两个过程
其中 BeanFactory 和ApplicationContext 是Spring 两种很重要的容器,BeanFactory 是Spring 里面最底层的接口,只提供了最简单的容器功能,包括实例化对象和获取对象的功能。
ApplicationContext 对BeanFactory进行了扩展,比如:增加了事件传播、资源访问、国际化消息访问等功能。一般所说的Spring Bean的生命周期其实是ApplicationContext容器的Bean的生命周期
创建Bean 会经过一系列的步骤,主要包括:
![](https://img.haomeiwen.com/i1510669/f42f8dd39a4676fc.png)
ApplicationContext容器中,Bean 的生命周期流程如上图所示,流程大致如下:
创建过程
1、首先容器启动后,会对scope为singleton且非懒加载的bean 进行实例化
2、按照Bean定义配置信息,注入所有的属性
3、如果Bean实现了BeanNameAware接口,会回调该接口的setBeanName()方法,传入该Bean的id,此时该Bean就获得了自己在配置文件中的id
4、如果Bean实现了BeanFactoryAware接口,会回调该接口的setBeanFactory()方法,传入该Bean的BeanFactory,这样该Bean就获得了自己所在的BeanFacory容器
5、如果Bean实现了ApplicationContextAware接口,会回调该接口的setApplicationContext()方法,传入该Beand 的ApplicationContext,这样Bean就获得了自己所在的ApplicationContext容器
6、如果Bean实现了BeanPostProcessor接口,就会回调该接口的postProcessBeforeInitialization()方法
7、如果Bean实现了InitializaingBean接口,则会回调该接口的afterPropertiesSet()方法。
8、如果Bean配置了init-method方法,则会执行init-method配置的方法
9、如果有Bean实现了BeanPostProcessor接口,则会回调该接口的postProcessAfterInitialization()方法,至此Bean的创建过程完毕
销毁过程
10、经过上面九个流程之后,就可以正式使用该Bean了,对于scope为singleton的Bean ,Spring的ioc容器中会缓存一份该bean的实例,对于scope为prototype的Bean,每次被调用都会new一个新的对象,其生命周期就交给调用方管理了,不再是Spring容器进行管理。
11、容器关闭之后,如果Bean实现了DisposableBean接口,则会回调该接口的destroy()方法。
12、如果Bean配置了destroy-method方法,则会执行destroy-method配置的方法,至此整个Bean的生命周期结束。
BeanFactoryPostProcessor 提供一个扩展机会,在bean还没有实例化的过程中,可以修改bean定义的属性。
Spring 整合mybaits与事务、spring cloud 整合feign都是在BeanFactoryPostProcessor中完成的
Spring Bean作用域
Spring Bean 有五个作用域,其中最基础的有下面两种:
Singleton 这是Spring的默认作用域,也就是为每个IOC 容器创建唯一的一个Bean实例。
Prototype 针对每个getBean请求,容器都会单独创建一个Bean实例。
从Bean的特点来看,Prototype适合有状态的Bean,而Singleton则更适合无状态的情况。另外,使用Prototype作用域需要经过仔细思考,比较频繁创建和销毁Bean是有明显开销的。
如果是Web容器,比如WebApplicationContext则支持另外三种作用域
Request:为每个HTTP 请求创建单独的Bean实例。
Session:很显然Bean实例的作用域是Session范围。
GlobalSession:用于Portlet容器,因为每个Portlet有单独的Session,GlobalSession提供一个全局性的HTTP Session
Spring的三大核心接口——BeanFactory、ApplicationContext、WebApplicationContext的区别
BeanFactory和ApplicationContext初始化区别:BeanFactory在初始化容器时并没有实例化Bean,而是在第一次访问到目标Bean时才实例化Bean;而ApplicationContext会在初始化上下文时实例化所有的单例的Bean
WebApplicationContext和BeanFactory、ApplicationContext初始化的区别:WebApplicationContext的初始化需要ServletContext实例,即初始化需要拥有web容器,需要在web.xml中配置自启动的servlet或web容器监听器(ServletContextListener)。
网友评论