Bean的生命周期

Posted jdy1022

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Bean的生命周期相关的知识,希望对你有一定的参考价值。

bean的生命周期:bean的创建---->bean的初始化--->bean的销毁,Bean的生命周期由容器来管理,Coder可以自定义初始化和销毁方法,容器在bean进行到当前生命周期的时候来调用编写的自定义的初始化和销毁方法。

1、管理生命周期的方式

  1. 指定初始化和销毁方法。

  2. 通过让Bean实现InitializingBean接口(定义初始化),DisposableBean接口(定义销毁)。

  3. 使用JSR250的@PostConstruct和@PreDestroy。

  4. 通过Bean的后置处理器BeanPostProcessor

2、生命周期的时机:

  • 构造(对象创建):

    • 单实例:在容器启动的时候创建对象

    • 多实例:在每次获取的时候创建

  • 初始化:

    • 对象创建完成,并赋值好,调用出初始化方法

  • 销毁:

    • 单实例容器关闭时销毁

    • 多实例容器不会管理多实例bean的销毁。

一、指定初始化和销毁方法

  使用initMethod/destoryMethod指定初始化和销毁方法

@Repository
public class Person {
    
    public Person() {
        System.out.println("person的无参构造器");
    }

    public void initMethod(){
        System.out.println("初始化方法");
    }

    public void destoryMethod(){
        System.out.println("销毁方法");
    }
}
  • 主配置类
@Configuration
public class MyConfigOfLifeCycle {
    @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    @Bean(initMethod = "initMethod",destroyMethod = "destoryMethod")
    public Person person(){
        return new Person();
    }
}
  • 测试
public void test08(){
     // 单实例bean,创建IOC容器时就会调用bean的构造器创建单实例bean,同时调用initMethod初始化方法
      //多实例bean,是在获取bean的实例时创建bean,同时调用initMethod初始化方法
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfigOfLifeCycle.class);
        Person perosn = context.getBean("person", Person.class);
         //关闭容器时,调用bean销毁方法
        context.close();
    }

二、实现InitializingBean和DisposableBean接口

public class Cat implements InitializingBean, DisposableBean {

    public Cat() {
        System.out.println("Cat的无参构造器");
    }
        
      //在属性设置完成之后调用
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("afterPropertiesSet ======= " );
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("destroy ======= " );
    }
}
  • 主配置类
@Configuration
public class MyConfigOfLifeCycle {

    @Bean
    public Cat cat(){
        return new Cat();
    }
}
  • 测试
@Test
    public void test09(){
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfigOfLifeCycle.class);
        Cat cat = context.getBean("cat", Cat.class);
        //关闭容器时,调用bean销毁方法
        context.close();
    }

三、使用JSR250

  • @PostConstruct:在Bean创建完成并且属性赋值完成,来执行初始化方法

  • @PreDestroy:在容器销毁Bean之前通知我们进行清理工作

@Component
public class Student {
   
    public Student() {
        System.out.println("student construct.....");
    }
    //对象创建并且赋值之后
    @PostConstruct
    public void init(){
        System.out.println("init......");
    }
    //容器销毁之前
    @PreDestroy
    public void destory(){
        System.out.println("destory......");
    }
}
  • 主配置类
@Configuration
@ComponentScan(basePackages="com.jdy.bean")
public class MyConfigOfLifeCycle {
   
}

四、Bean的后置处理器

在Bean初始化前后进行处理工作,针对是IOC容易中每一个Bean。

  • postProcessBeforeInitialization:Bean初始化之前进行处理

  • postProcessAfterInitialization:Bean初始化之后进行处理

  创建后置处理器实现BeanPostProcessor接口

/**
 * @author Mr.jdy
 * @create 2020-07-11 20:40
 * 后置处理器在初始化前后执行
 *            bean:IOC容器中创建的Bean
 *             beanName:IOC容器中Bean的名字
 * 可以在MyProcessor中打断点查看
 */
@Component
public class MyProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println(beanName+"==postProcessBeforeInitialization....");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println(beanName+"==postProcessAfterInitialization....");
        return bean;
    }
}
  • 主配置类
@Configuration
@ComponentScan(basePackages={"com.jdy.bean","com.jdy.processor"})
public class MyConfigOfLifeCycle {
}

五、BeanPostProcessor原理

以上是关于Bean的生命周期的主要内容,如果未能解决你的问题,请参考以下文章

Spring事务,Bean生命周期

关于片段生命周期

调用 replace() 时片段的生命周期是啥?

Spring应用上下文中Bean的生命周期

Spring 的 Bean 生命周期,11 张高清流程图及代码,深度解析

在不存在的片段上调用片段生命周期和 onCreate 的问题