Spring Bean的生命周期

22 24~32 min

Aware接口

Spring IoC 整体流程总结

生命周期

第一步,创建一个 LifecycleDemoBean 类:

public class LifecycleDemoBean implements InitializingBean, DisposableBean {

    // 使用@Value注解注入属性值,这里演示了如何从配置文件中读取值
    // 如果配置文件中没有定义lifecycle.demo.bean.name,则使用默认值"default name"
    @Value("${lifecycle.demo.bean.name:default name}")
    private String name;

    // 构造方法:在Bean实例化时调用
    public LifecycleDemoBean() {
        System.out.println("LifecycleDemoBean: 实例化");
    }

    // 属性赋值:Spring通过反射调用setter方法为Bean的属性注入值
    public void setName(String name) {
        System.out.println("LifecycleDemoBean: 属性赋值");
        this.name = name;
    }

    // 使用@PostConstruct注解的方法:在Bean的属性赋值完成后调用,用于执行初始化逻辑
    @PostConstruct
    public void postConstruct() {
        System.out.println("LifecycleDemoBean: @PostConstruct(初始化)");
    }

    // 实现InitializingBean接口:afterPropertiesSet方法在@PostConstruct注解的方法之后调用
    // 用于执行更多的初始化逻辑
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("LifecycleDemoBean: afterPropertiesSet(InitializingBean)");
    }

    // 自定义初始化方法:在XML配置或Java配置中指定,执行特定的初始化逻辑
    public void customInit() {
        System.out.println("LifecycleDemoBean: customInit(自定义初始化方法)");
    }

    // 使用@PreDestroy注解的方法:在容器销毁Bean之前调用,用于执行清理工作
    @PreDestroy
    public void preDestroy() {
        System.out.println("LifecycleDemoBean: @PreDestroy(销毁前)");
    }

    // 实现DisposableBean接口:destroy方法在@PreDestroy注解的方法之后调用
    // 用于执行清理资源等销毁逻辑
    @Override
    public void destroy() throws Exception {
        System.out.println("LifecycleDemoBean: destroy(DisposableBean)");
    }

    // 自定义销毁方法:在XML配置或Java配置中指定,执行特定的清理逻辑
    public void customDestroy() {
        System.out.println("LifecycleDemoBean: customDestroy(自定义销毁方法)");
    }
}

①、实例化

实例化是创建 Bean 实例的过程,即在内存中为 Bean 对象分配空间。这一步是通过调用 Bean 的构造方法完成的。

public LifecycleDemoBean() {
    System.out.println("LifecycleDemoBean: 实例化");
}

在这里,当 Spring 创建 LifecycleDemoBean 的实例时,会调用其无参数的构造方法,这个过程就是实例化。

②、属性赋值

在实例化之后,Spring 将根据 Bean 定义中的配置信息,通过反射机制为 Bean 的属性赋值。

@Value("${lifecycle.demo.bean.name:default name}")
private String name;

public void setName(String name) {
    System.out.println("LifecycleDemoBean: 属性赋值");
    this.name = name;
}

@Value注解和 setter 方法体现了属性赋值的过程。@Value注解让 Spring 注入配置值(或默认值),setter 方法则是属性赋值的具体操作。

③、初始化

初始化阶段允许执行自定义的初始化逻辑,比如检查必要的属性是否已经设置、开启资源等。Spring 提供了多种方式来配置初始化逻辑。

1、使用 @PostConstruct 注解的方法

@PostConstruct
public void postConstruct() {
    System.out.println("LifecycleDemoBean: @PostConstruct(初始化)");
}

@PostConstruct注解的方法在 Bean 的所有属性都被赋值后,且用户自定义的初始化方法之前调用。

2、实现 InitializingBean 接口的 afterPropertiesSet 方法

@Override
public void afterPropertiesSet() throws Exception {
    System.out.println("LifecycleDemoBean: afterPropertiesSet(InitializingBean)");
}

afterPropertiesSet 方法提供了另一种初始化 Bean 的方式,也是在所有属性赋值后调用。

3、自定义初始化方法

public void customInit() {
    System.out.println("LifecycleDemoBean: customInit(自定义初始化方法)");
}

需要在配置类中指定初始化方法:

@Bean(initMethod = "customInit")
public LifecycleDemoBean lifecycleDemoBean() {
    return new LifecycleDemoBean();
}

④、销毁

销毁阶段允许执行自定义的销毁逻辑,比如释放资源。类似于初始化阶段,Spring 也提供了多种方式来配置销毁逻辑。

1、使用 @PreDestroy 注解的方法

@PreDestroy
public void preDestroy() {
    System.out.println("LifecycleDemoBean: @PreDestroy(销毁前)");
}

@PreDestroy注解的方法在 Bean 被销毁前调用。

2、实现 DisposableBean 接口的 destroy 方法

@Override
public void destroy() throws Exception {
    System.out.println("LifecycleDemoBean: destroy(DisposableBean)");
}

destroy 方法提供了另一种销毁 Bean 的方式,也是在 Bean 被销毁前调用。

3、自定义销毁方法

public void customDestroy() {
    System.out.println("LifecycleDemoBean: customDestroy(自定义销毁方法)");
}

需要在配置类中指定销毁方法:

@Bean(destroyMethod = "customDestroy")
public LifecycleDemoBean lifecycleDemoBean() {
    return new LifecycleDemoBean();
}

第二步,注册 Bean 并指定自定义初始化方法和销毁方法:

@Configuration
public class LifecycleDemoConfig {

    @Bean(initMethod = "customInit", destroyMethod = "customDestroy")
    public LifecycleDemoBean lifecycleDemoBean() {
        return new LifecycleDemoBean();
    }
}

第三步,编写单元测试:

@SpringBootTest
public class LifecycleDemoTest {

    @Autowired
    private ApplicationContext context;

    @Test
    public void testBeanLifecycle() {
        System.out.println("获取LifecycleDemoBean实例...");
        LifecycleDemoBean bean = context.getBean(LifecycleDemoBean.class);
    }
}

运行单元测试,查看控制台输出:

LifecycleDemoBean: 实例化
LifecycleDemoBean: @PostConstruct(初始化)
LifecycleDemoBean: afterPropertiesSet(InitializingBean)
LifecycleDemoBean: customInit(自定义初始化方法)
获取LifecycleDemoBean实例...
LifecycleDemoBean: @PreDestroy(销毁前)
LifecycleDemoBean: destroy(DisposableBean)
LifecycleDemoBean: customDestroy(自定义销毁方法)