Spring由繁入简——一叶一菩提:Bean的生命周期

发布于:2025-06-20 ⋅ 阅读:(22) ⋅ 点赞:(0)

基本生命周期

概述

Spring的生命周期也就是从创建到销毁的所有阶段
默认情况下,IOC容器中bean的生命周期分为五个阶段:

1. 实例化 Bean
2. 属性赋值
3. 初始化 Bean
4. 使用
5. 销毁Bean对象
  1. 实例化
    调用无参构造器或者通过工厂方式创建Bean实例对象

  2. 属性赋值
    给bean对象的属性注入值

    • 构造器注入:通过构造方法将依赖注入到目标对象中,实例化和属性赋值同时发生。
    • Setter 方法注入:通过 Setter 方法将依赖注入到目标对象中,先实例化,再进行属性赋值。
    • 字段注入:通过字段直接注入依赖,先实例化,再进行属性赋值。
  3. 初始化
    在 Bean 实例化并完成属性赋值后,Spring 容器会调用初始化方法来完成 Bean 的初始化。
    初始化时的方法:

    • @PostConstruct 注解:标注在方法上,表示该方法在 Bean 初始化时被调用。
    @Service
    public class OrderServiceImpl implements OrderService{
       final OrderDao orderDao;
       @PostConstruct
       public void init() {
    		// 初始化一些内容
       }
     }
    
    • InitializingBean 接口:实现该接口的 afterPropertiesSet() 方法。
    @Service
    public class OrderServiceImpl implements OrderService , InitializingBean {
        final OrderDao orderDao;
        @Override
        public void afterPropertiesSet() throws Exception {
    			// 初始化一些内容
        }
    }
    
    • init-method 属性:在 XML 配置中指定初始化方法。
      <bean id="myBean" class="com.example.MyBean" init-method="init" />
    public class MyBean {
        public void init() {
            System.out.println("Bean 初始化: " + this.getClass().getName());
        }
    }
    
    • 如果是通过参数注入的,使用 @Bean 注解的 initMethod 属性(Java 配置)
    @Configuration
    public class AppConfig {
        @Bean(initMethod = "init")
        public MyBean myBean() {
            return new MyBean();
        }
    }
    
    public class MyBean {
        public void init() {
            System.out.println("Bean 初始化: " + this.getClass().getName());
        }
    }
    
  4. 使用
    Bean 初始化完成后,就可以被应用程序使用了。
    Spring 容器会将 Bean 放入 Bean 工厂中,供其他 Bean 或应用程序代码使用。

  5. 销毁Bean对象.
    当 SpringIOC容器关闭时,会调用销毁方法来清理资源。
    销毁时的几种方法(与初始化时使用方法一致)

    • @PreDestroy 注解:标注在方法上,表示该方法在 Bean 销毁时被调用。
    • DisposableBean 接口:实现该接口的 destroy() 方法。
    • destroy-method 属性:在 XML 配置中指定销毁方法。
    • 如果是通过参数注入的,使用 @Bean 注解的 destroyMethod属性(Java 配置)

测试

测试bean

@Service
public class BeanTimeTestService implements  InitializingBean , DisposableBean {
    private OrderDao orderDao;
	// 实例化
    BeanTimeTestService(){
        System.out.println("my BeanTimeTestService construct method");
    }
    // 属性赋值
    @Autowired
    public void setOrderDao(OrderDao orderDao) {
        System.out.println("my BeanTimeTestService setOrderDao");
    }
    // 使用
    public void test(){
        System.out.println("using");
    }
    // 销毁
    @Override
    public void destroy() throws Exception {
        System.out.println("destroy");
    }
	// 初始化
    @Override
    public void afterPropertiesSet()  {
        System.out.println("Bean " + this.getClass().getSimpleName()+ " afterPropertiesSet");
    }
    // 初始化
    @PostConstruct
    public void init() {
        System.out.println("Bean " + this.getClass().getSimpleName()+ " PostConstruct");
    }
}

结果

在这里插入图片描述

加入Bean的后置处理器

当加入了Bean的后置处理器后,IOC容器中bean的生命周期变为下面内容:

postProcessBeforeInstantiation
1. 实例化 Bean
postProcessAfterInstantiation
2. 属性赋值
postProcessBeforeInitialization
3. 初始化 Bean
postProcessAfterInitialization
4. 使用
5. 销毁Bean对象

在这里插入图片描述

什么是Bean后置处理器?

  • Bean 后置处理器(Bean Post Processor) 是 Spring 框架中的一种特殊机制,用于在 Bean 的初始化前后对 Bean 进行额外的处理。Spring 容器在初始化 Bean 时,会调用后置处理器来执行一些自定义逻辑。后置处理器可以用来修改 Bean 的行为、注入额外的依赖、验证 Bean 的状态等。
  • Spring 提供了两种类型的后置处理器:
    BeanPostProcessor:在 Bean 初始化前后执行逻辑。
    InstantiationAwareBeanPostProcessor:在 Bean 实例化时执行逻辑。

BeanPostProcessor接口

  • postProcessBeforeInitialization(Object bean, String beanName):在 Bean 初始化之前执行。

  • postProcessAfterInitialization(Object bean, String beanName):在 Bean 初始化之后执行。

    import org.springframework.beans.factory.config.BeanPostProcessor;
    import org.springframework.stereotype.Component;
    
    @Component
    public class MyBeanPostProcessor implements BeanPostProcessor {
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) {
            System.out.println("Bean " + beanName + " is being initialized");
            return bean;
        }
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) {
            System.out.println("Bean " + beanName + " has been initialized");
            return bean;
        }
    }
    

InstantiationAwareBeanPostProcessor接口

  • postProcessBeforeInstantiation(Class<?> beanClass, String beanName):在 Bean 实例化之前执行。
  • postProcessAfterInstantiation(Object bean, String beanName):在 Bean 实例化之后执行。
    import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
    import org.springframework.stereotype.Component;
    
    @Component
    public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
        @Override
        public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
            System.out.println("Bean " + beanName + " is about to be instantiated");
            return null; // 返回 null 表示不干预实例化过程
        }
    
        @Override
        public boolean postProcessAfterInstantiation(Object bean, String beanName) {
            System.out.println("Bean " + beanName + " has been instantiated");
            return true; // 返回 true 表示继续初始化过程
        }
    }
    

代码测试

通过上面MyBeanPostProcessorMyInstantiationAwareBeanPostProcessor 分别实现BeanPostProcessorInstantiationAwareBeanPostProcessor接口
新建测试bean

@Service
public class BeanTimeTestService implements  InitializingBean , DisposableBean {
    private OrderDao orderDao;

    BeanTimeTestService(){
        System.out.println("my BeanTimeTestService construct method");
    }
    @Autowired
    public void setOrderDao(OrderDao orderDao) {
        System.out.println("my BeanTimeTestService setOrderDao");
    }
    public void test(){
        System.out.println("using");
    }
    @Override
    public void destroy() throws Exception {
        System.out.println("destroy");
    }

    @Override
    public void afterPropertiesSet()  {
        System.out.println("Bean " + this.getClass().getSimpleName()+ " afterPropertiesSet");
    }
    @PostConstruct
    public void init() {
        System.out.println("Bean " + this.getClass().getSimpleName()+ " PostConstruct");

    }

}

结果

注意结果不在调用方法中,而是在整个阶段的生命周期中,调用的方法输出只有using

在这里插入图片描述
在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到