Spring 的 bean 是构建 Spring 应用中很重要的一部分,了解 Spring Bean 的相关细节对于解读 Spring 框架很重要。

  • 1、Spring4 bean 作用域 scope
  • 2、bean 创建的三种方式
  • 3、ApplicationContext 容器中的 bean 生命周期
  • 4、BeanFactory 容器中的 bean 生命周期

1、Spring4 bean 的作用域 scope

通过使用 Bean 定义来指定实例的作用域(scope),而不需要在 Java 的类级别来完成这个任务,这种方法非常强大和灵活。Spring 框架现有五种作用域,其中有三个需要在使用 Web 相关的 ApplicationContext 环境下才可以使用。

1.1 singleton:默认的作用域,仅为每个 Bean 对象创建一个实例

把一个 bean 定义设置为 singlton 作用域时,Spring IoC 容器只会创建该 bean 定义的唯一实例。这个单一实例会被存储到单例缓存(singleton cache)中,并且所有针对该 bean 的后续请求和引用都将返回被缓存的对象实例。

1.2 prototype:可以根据需要为每个 Bean 对象创建多个实例

Prototype 作用域的 bean 会导致在每次对该 bean 请求(将其注入到另一个 bean 中,或者以程序的方式调用容器的 getBean() 方法)时都会创建一个新的 bean 实例。根据经验,对所有有状态的 bean 应该使用 prototype 作用域,而对无状态的 bean 则应该使用 singleton 作用域。
请注意,典型情况下,DAO 不会被配置成 prototype,因为一个典型的 DAO 不会持有任何会话状态,因此应该使用 singleton 作用域。

1.3 web 作用域

1.3.1 request:为每个 HTTP 请求创建它自有的一个 Bean 实例,仅在 Web 相关的 ApplicationContext 中生效。
1.3.2 session:为每个 HTTP 会话创建一个实例,仅在 Web 相关的 ApplicationContext 中生效。
1.3.3 global session:为每个全局的 HTTP 会话创建一个实例。一般仅在 porlet 上下文中用生效。同时仅在 Web 相关的 ApplicationContext 中生效。

2、bean 创建的三种方式

2.1 调用构造器创建 Bean
2.2 调用静态工厂方法创建 Bean
2.3 调用实例工厂方法创建 Bean

3、ApplicationContext 容器中的 bean 生命周期

BeanFactory 和 ApplicationContext 是 Spring 两种很重要的容器, 前者提供了最基本的依赖注入的支持,而后者在继承前者的基础进行了功能的拓展,例如增加了事件传播,资源访问和国际化的消息访问等功能。分别介绍 ApplicationContext 和 BeanFactory 两种容器的 Bean 的生命周期。
spring4 bean的作用域scope 创建及生命周期 - 图1

ApplicationContext 容器中,Bean 的生命周期流程如上图所示,流程大致如下:

  1. 首先容器启动后,会对 scope 为 singleton 且非懒加载的 bean 进行实例化,

  2. 按照 Bean 定义信息配置信息,注入所有的属性,

  3. 如果 Bean 实现了 BeanNameAware 接口,会回调该接口的 setBeanName() 方法,传入该 Bean 的 id,此时该 Bean 就获得了自己在配置文件中的 id,

  4. 如果 Bean 实现了 BeanFactoryAware 接口, 会回调该接口的 setBeanFactory() 方法,传入该 Bean 的 BeanFactory,这样该 Bean 就获得了自己所在的 BeanFactory,

  5. 如果 Bean 实现了 ApplicationContextAware 接口, 会回调该接口的 setApplicationContext() 方法,传入该 Bean 的 ApplicationContext,这样该 Bean 就获得了自己所在的 ApplicationContext,

  6. 如果有 Bean 实现了 BeanPostProcessor 接口,则会回调该接口的 postProcessBeforeInitialzation() 方法,

  7. 如果 Bean 实现了 InitializingBean 接口,则会回调该接口的 afterPropertiesSet() 方法,

  8. 如果 Bean 配置了 init-method 方法,则会执行 init-method 配置的方法,

  9. 如果有 Bean 实现了 BeanPostProcessor 接口,则会回调该接口的 postProcessAfterInitialization() 方法,

  10. 经过流程 9 之后,就可以正式使用该 Bean 了, 对于 scope 为 singleton 的 Bean,Spring 的 ioc 容器中会缓存一份该 bean 的实例,而对于 scope 为 prototype 的 Bean, 每次被调用都会 new 一个新的对象,期生命周期就交给调用方管理了,不再是 Spring 容器进行管理了

  11. 容器关闭后,如果 Bean 实现了 DisposableBean 接口,则会回调该接口的 destroy() 方法,

  12. 如果 Bean 配置了 destroy-method 方法,则会执行 destroy-method 配置的方法,至此,整个 Bean 的生命周期结束

3、BeanFactory 容器中的 bean 生命周期

spring4 bean的作用域scope 创建及生命周期 - 图2

BeanFactoty 容器中, Bean 的生命周期如上图所示,与 ApplicationContext 相比,有如下几点不同:

1.BeanFactory 容器中,不会调用 ApplicationContextAware 接口的 setApplicationContext() 方法,

2.BeanPostProcessor 接口的 postProcessBeforeInitialzation() 方法和 postProcessAfterInitialization() 方法不会自动调用,必须自己通过代码手动注册

3.BeanFactory 容器启动的时候,不会去实例化所有 Bean, 包括所有 scope 为 singleton 且非懒加载的 Bean 也是一样,而是在调用的时候去实例化。
https://blog.csdn.net/sinat_34351851/article/details/79685998