Bean的作用域

一般来说,普通的java对象的生命周期可以如下描述:

  • (类加载)—>实例化
  • 对象不再被使用时通过垃圾回收机制进行回收
    而Bean,也不过是spring通过IOC容器管理的一些特殊的对象,Bean的作用域有以下几种(可以用@Scope注解指定):
  1. 单例(singleton)在整个应用中只创建一个 Bean 实例
  2. 原型(prototype)每次请求时都创建一个新的 Bean 实例
  3. 请求(request)一次 HTTP 请求中,创建一个 Bean 实例
  4. 会话(session)用户会话中创建一个 Bean 实例
  5. 全局会话(Global Session )类似于 Session 作用域,但用于 Portlet 环境
  6. 应用(application)在整个 Web 应用的生命周期中创建一个 Bean 实例
    其中,后四个作用域是在 Web 环境下使用的

生命周期

本文讨论单例模式下的Bean的生命周期,因为它完全被IOC容器控制
对于Spring Bean的生命周期来说,可以分为四个阶段,其中初始化完成之后,就代表这个Bean可以使用了:

  1. 实例化(Instantiation):在这个阶段,Spring 容器根据配置信息创建 Bean 的实例。根据配置的作用域(singleton、prototype 等),实例化可能发生在容器启动时(单例)或每次请求时(原型)。
  2. 属性赋值(Population):在实例化之后,Spring 容器将会通过依赖注入或者其他方式将配置的属性值注入到 Bean 实例中,这个过程也被称为属性赋值。
  3. 初始化前回调(Initialization callback):在属性赋值完成之后,Spring 容器会调用 Bean 的初始化方法(如果有配置的话),以便进行一些初始化操作。常见的初始化方法包括 init-method 方法和 @PostConstruct 注解标记的方法。
  4. 初始化后回调(Initialization callback):在初始化方法执行完成后,Spring 容器会触发相应的事件,以通知 Bean 实例已经初始化完成。这个时候 Bean 实例已经完全可用。
  5. 销毁前回调(Destruction callback):对于 singleton 作用域的 Bean,当容器关闭时或者手动销毁 Bean 时,Spring 容器会调用 Bean 的销毁方法,执行一些清理操作。常见的销毁方法包括 destroy-method 方法和 @PreDestroy 注解标记的方法。

额外操作

在Bean的生命周期中,还可以有一些额外操作来便于我们进一步控制和管理它们:

  1. 实例化阶段
    • 在实例化阶段,Spring 容器会根据配置信息创建 Bean 的实例。这通常发生在容器启动时(对于 singleton 作用域的 Bean)或者在每次请求时(对于 prototype 作用域的 Bean)。
    • 在这个阶段,可以通过自定义 BeanPostProcessor 实现类来进行扩展。BeanPostProcessor 接口提供了两个回调方法:postProcessBeforeInitialization()postProcessAfterInitialization(),分别表示在 Bean 的初始化前和初始化后执行一些操作。
    • Bean还可以实现Aware接口,从而获得与容器交互的能力,以便获取一些容器管理的资源或者在特定的时机得到一些回调。当一个 Bean 实现了某个 Aware 接口时,Spring 容器在初始化该 Bean 时会自动调用相应的回调方法,从而将相应的资源或者引用注入到 Bean 中,例如名称,工厂,上下文等。
  2. 初始化阶段
    • 在初始化阶段,Spring 容器会调用 Bean 的初始化方法,这个方法可以是通过配置的 init-method 属性指定的方法,也可以是使用 @PostConstruct 注解标记的方法。
    • 在这个阶段,可以执行一些初始化操作,如数据初始化、资源加载等。同时,也可以通过自定义的 BeanPostProcessor 实现类在初始化前后执行一些操作。
  3. 使用阶段
    • 在使用阶段,Bean 已经被完全初始化,并且可以被其他组件或者代码调用和使用。
    • 在这个阶段,Bean 被容器管理,可以被注入到其他 Bean 中,也可以被注入到 AOP 切面中进行增强等操作。
  4. 销毁阶段
    • 在销毁阶段,Spring 容器会关闭时或者手动销毁 Bean 时,会调用 Bean 的销毁方法。这个方法可以是通过配置的 destroy-method 属性指定的方法,也可以是使用 @PreDestroy 注解标记的方法。
    • 在这个阶段,可以执行一些清理操作,如释放资源、关闭连接等。

总结

Bean的生命周期:

  1. 通过BeanDefinition获取bean的定义信息,这里面就封装了bean的所有信息,比如,类的全路径,是否是延迟加载,是否是单例等等。
  2. 开始创建bean,调用构造函数实例化bean,这一步包括:
    • 依赖注入,比如一些set方法注入,也就是属性赋值,平时开发用的@Autowire都是这一步完成
    • 处理Aware接口,如果某一个bean实现了Aware接口就会重写对应的Aware中的方法
    • bean的后置处理器BeanPostProcessor,这个是前置处理器
  3. 初始化方法,比如实现了接口InitializingBean或者自定义了方法init-method标签或@PostContruct
  4. 执行bean的后置处理器BeanPostProcessor,主要是对bean进行增强,有可能在这里产生代理对象
  5. 销毁bean,在销毁之前,检查是否实现DisposableBean接口或配置自定义destory-method方法,如果有,先执行这些方法然后销毁bean。
图片损坏
1
2
3
4
5
6
7
8
9
10
1.调用构造方法:开始实例化
2.设置属性:属性赋值
3.调用BeanNameAware#setBeanName方法: Aware接口处理
4.调用BeanFactoryAware#setBeanFactory方法: Aware接口处理
5.BeanPostProcessor#postProcessBeforeInitialization方法:前置处理器方法
6.InitializingBean#afterPropertiesSet方法:初始化
7.自定义init方法:初始化
8.BeanPostProcessor#postProcessAfterInitialization方法:后置处理器方法
9.DisposableBean#destroy方法:销毁
10.自定义destroy方法:销毁