【Spring】Bean 的生命周期

什么是 Bean 的生命周期

Spring 是一个管理 Bean 的容器,它负责对象的创建、对象之间关系的维护 / 依赖的维护、对象的销毁等。所谓 Bean 的生命周期就是:对象从创建到最终销毁的整个过程。其实我们研究生命周期主要研究的是:在哪个时间节点上调用了哪个方法。所以我们需要着重了解在这个生命线上都有哪些特殊的时间节点。了解了这些特殊的时间节点之后,我们才能确定代码该写在哪里,才能保证当生命线走到这个节点时,代码会被执行。

Bean 的生命周期之五步

Bean 的生命周期可以粗略的划分为五大步:

  • 第一步:实例化 Bean
  • 第二步:Bean 属性赋值
  • 第三步:初始化 Bean
  • 第四步:使用 Bean
  • 第五步:销毁 Bean

 编写测试程序:

/**
 * 定义一个普通的 Java 类
 */
@Component
public class User {
    private String name;

    public User() {
        System.out.println("1.实例化bean");
    }

    @Value("张三")
    public void setName(String name) {
        this.name = name;
        System.out.println("2.bean属性赋值");
    }

    @PostConstruct
    public void initBean() {
        System.out.println("3.初始化bean");
    }

    public void doSome() {
        System.out.println("4.使用bean");
    }

    @PreDestroy
    public void destroyBean() {
        System.out.println("5.销毁bean");
    }
}
/**
 * Spring 核心配置类
 */
@Configuration
@ComponentScan("com.ltb.demo")
public class ContextConfig {
}
/**
 * 测试类
 */
class UserTest {

    @Test
    void test1() {
        ApplicationContext context = new AnnotationConfigApplicationContext(ContextConfig.class);
        User user = context.getBean("user", User.class);
        user.doSome();
        ((AnnotationConfigApplicationContext) context).close();
    }

}

测试方法执行结果:

注意:

  • 使用 @PostConstruct 来标识一个初始化方法,这个方法是程序员自定义的

  • 使用 @PreDestroy 来标识一个销毁方法,这个方法也是程序员自定义的

  • 只有正常关闭 spring 容器,bean 的销毁方法才会被调用

这两个注解属于 JDK 扩展包,所以不在 JDK 当中,需要额外引入以下依赖:【如果是 JDK8 的话不需要引入。高于 JDK11 或低于 JDK8 需要引入】

<dependency>
  <groupId>jakarta.annotation</groupId>
  <artifactId>jakarta.annotation-api</artifactId>
  <version>2.1.1</version>
</dependency>

一定要注意:如果你用 Spring 6,要知道 Spring 6 不再支持 JavaEE,它支持的是  JakartaEE9。(Oracle 把 JavaEE 贡献给 Apache 了,Apache 把 JavaEE 的名字改成 JakartaEE 了,大家之前所接触的所有的 javax.* 包名统一修改为 jakarta.* 包名了)

Bean 的生命周期之七步

在以上的 5 步中,第 3 步是初始化 Bean,如果你还想在初始化前后添加代码,可以加入 "Bean 后处理器"

编写一个类,实现 BeanPostProcessor 接口,并将这个类对象交给 Spring 容器管理,那么这个类就是一个 Bean 后处理器了。代码如下:

@Component
public class LogBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("Bean 后处理器的 before 方法执行,即将开始初始化");
        return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("Bean 后处理器的 after 方法执行,已完成初始化");
        return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
    }
}

注意:如果是在 XML 文件中配置的 Bean 后处理器将只会作用于当前配置文件中所有的 Bean。

其他代码均不变,重新运行测试方法,运行结果如下:

如果加上后处理器的话,Bean 的生命周期就是七步了:

Bean 的生命周期之十步 

Bean 的生命周期步骤还可以更细粒度的划分,在七步的基础上,分别在后处理器的 before 方法前和后、销毁 Bean 前再各加一步,构成 Bean 生命周期的十个阶段。

 相关接口如下:

  • BeanNameAware:Spring 会将 Bean 的名字传给这个接口的实现方法。
  • BeanClassLoaderAware:Spring 会将加载这个 Bean 的类加载器传给这个接口的实现方法。
  • BeanFactoryAware:Spring 会将生产这个 Bean 的工厂传给这个接口的实现方法。
  • InitializingBean:这个接口的方法,会在后处理器的 before 执行之后,Bean 初始化方法执行之前执行。
  • DisposableBean:这个接口的方法,会在销毁 Bean 方法执行之前执行。

其中,Aware 接口的方法执行时机是属性赋值完之后、后处理器 before 执行之前执行。

具体代码非常简单这里就不编写了,直接上运行结果:

Bean 的作用域不同,管理方式不同

Spring  根据 Bean 的作用域来选择管理方式,作用域是 singleton 的 Bean,Spring 能够精准地知道该 Bean 什么时候被初始化,什么时候被销毁,所以可以完完整整的走完上述的 10 个步骤;

对于作用域是 prototype 的 Bean,初始化好了之后 Spring 将不再负责,Bean 的实例交给程序员管理,Spring 不再追踪其生命周期,所以只有上述 10 个步骤的前 8 步。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小李哞哞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值