spring中bean的生命周期

下面我将通过一个具体的 Java 示例,详细说明 Spring 中 Bean 的生命周期各个阶段,并为每一步添加注释解释其作用。


1. 实例化 Bean(为 Bean 分配内存空间)

Spring 容器根据配置信息创建一个 Bean 的实例(调用构造函数)。

public class MyBean {

    public MyBean() {
        System.out.println("1. Bean 被实例化(构造方法调用)");
    }
}

做了什么?
JVM 为 MyBean 对象分配内存空间,并调用无参构造函数初始化对象。


⚙️ 2. 设置属性(Bean 注入和装配)

如果 Bean 有依赖项或需要注入的值,Spring 会进行依赖注入。

public class MyBean {

    private String message;

    public void setMessage(String message) {
        this.message = message;
        System.out.println("2. 属性注入:setMessage(" + message + ")");
    }

    // ...
}

做了什么?
Spring 调用了 setMessage("Hello") 方法,把配置文件中定义的值注入到 Bean 中。


3. Bean 初始化阶段

3.1 实现了各种 Aware 接口的方法

这些接口允许 Bean 获取容器中的关键组件,如名称、工厂、上下文等。

@Component
public class MyBean implements BeanNameAware, ApplicationContextAware {

    @Override
    public void setBeanName(String name) {
        System.out.println("3.1.1 setBeanName: Bean 名称是 " + name);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) {
        System.out.println("3.1.2 setApplicationContext: 应用上下文已设置");
    }

    // ...
}

做了什么?

  • setBeanName() 让 Bean 知道自己在容器中的名字。
  • setApplicationContext() 提供对整个 Spring 容器的访问。

3.2 执行 BeanPostProcessor 初始化前置方法

如果有自定义的 BeanPostProcessor,它会在初始化前处理这个 Bean。

@Component
public class MyBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) {
        if (bean instanceof MyBean) {
            System.out.println("3.2 postProcessBeforeInitialization: Bean 初始化前处理");
        }
        return bean;
    }
}

做了什么?
这是插件机制的一部分,可以在所有 Bean 初始化之前做一些通用处理,比如日志记录、代理增强等。


3.3 执行 @PostConstruct 初始化方法(依赖注入后执行)

该注解用于标记在依赖注入完成后要执行的初始化逻辑。

@PostConstruct
public void postConstruct() {
    System.out.println("3.3 @PostConstruct: 初始化方法,在依赖注入之后执行");
}

做了什么?
这是一个非常常用的注解,适合做一些资源加载、连接池初始化等工作。


3.4 执行自定义 init-method 方法(如果有指定)

你也可以在 XML 或 @Bean 注解中指定一个初始化方法。

public class MyBean {

    public void customInitMethod() {
        System.out.println("3.4 自定义 init-method: 自定义初始化逻辑");
    }
}

XML 配置方式:

<bean id="myBean" class="com.example.MyBean" init-method="customInitMethod"/>

或者使用 @Bean

@Bean(initMethod = "customInitMethod")
public MyBean myBean() {
    return new MyBean();
}

做了什么?
提供了一种与 Spring 解耦的方式来执行初始化逻辑。


3.5 执行 BeanPostProcessor 初始化后置方法

和前置类似,但是在初始化之后执行。

@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
    if (bean instanceof MyBean) {
        System.out.println("3.5 postProcessAfterInitialization: Bean 初始化后处理");
    }
    return bean;
}

做了什么?
可用于 AOP 代理生成、日志增强等操作。


‍ 4. 使用 Bean

此时 Bean 已经完全准备好,可以被正常使用。

@Service
public class MyService {

    @Autowired
    private MyBean myBean;

    public void useBean() {
        System.out.println("4. 使用 Bean");
    }
}

做了什么?
Bean 可以参与业务逻辑,被其他组件调用。


5. 销毁 Bean

当 Spring 容器关闭时,会执行销毁逻辑。

5.1 @PreDestroy 注解方法

@PreDestroy
public void preDestroy() {
    System.out.println("5.1 @PreDestroy: 在销毁前执行");
}

做了什么?
通常用来释放资源,如关闭数据库连接、线程池等。


5.2 实现 DisposableBean 接口

public class MyBean implements DisposableBean {

    @Override
    public void destroy() throws Exception {
        System.out.println("5.2 DisposableBean.destroy(): Spring 标准销毁方法");
    }
}

做了什么?
Spring 提供的标准销毁回调接口。


5.3 自定义 destroy-method

类似于 init-method,你可以指定一个销毁方法。

public class MyBean {

    public void customDestroyMethod() {
        System.out.println("5.3 自定义 destroy-method: 自定义销毁逻辑");
    }
}

XML 配置方式:

<bean id="myBean" class="com.example.MyBean" destroy-method="customDestroyMethod"/>

或者使用 @Bean

@Bean(destroyMethod = "customDestroyMethod")
public MyBean myBean() {
    return new MyBean();
}

做了什么?
提供了灵活的销毁逻辑配置方式。


✅ 总结:完整生命周期输出示例

如果你运行上面的代码,控制台输出大概是这样的顺序:

1. Bean 被实例化(构造方法调用)
2. 属性注入:setMessage(Hello)
3.1.1 setBeanName: Bean 名称是 myBean
3.1.2 setApplicationContext: 应用上下文已设置
3.2 postProcessBeforeInitialization: Bean 初始化前处理
3.3 @PostConstruct: 初始化方法,在依赖注入之后执行
3.4 自定义 init-method: 自定义初始化逻辑
3.5 postProcessAfterInitialization: Bean 初始化后处理
4. 使用 Bean
...
5.1 @PreDestroy: 在销毁前执行
5.2 DisposableBean.destroy(): Spring 标准销毁方法
5.3 自定义 destroy-method: 自定义销毁逻辑

小贴士:Spring Boot 中自动触发销毁方法?

在 Spring Boot 中,如果你想让 @PreDestroydestroy-method 正常执行,必须确保应用是正常关闭的。例如:

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);
        
        // 模拟运行一段时间
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // 正常关闭容器
        context.close();
    }
}

否则,直接结束进程(如 Ctrl+C),可能会跳过销毁阶段。

你可能感兴趣的:(java,spring)