• 七、spring生命周期之初始化和销毁方法


    一、通过@Bean指定初始化和销毁方法

    在以往的xml中,我们是这样配置的

    <bean id="exampleInitBean" class="examples.ExampleBean" init-method="init" destroy-method="cleanup"/>
    

    那如果采用注解 的方式该如何配置呢?

    首先我们创建一个Car,

    public class Car {
    	
    	public Car(){
    		System.out.println("car constructor...");  // 构造方法
    	}
    	
    	public void init(){
    		System.out.println("car ... init..."); // 初始化方法
    	}
    	
    	public void detory(){
    		System.out.println("car ... detory..."); // 销毁方法
    	}
    
    }
    
    

    我们需要通过配置类将这个Car注册进容器中,当然这很简单。

    @Configuration
    public class MainConfigOfLifeCycle {
    	
    	//@Scope("prototype")
       	@Scope("singleton") // 默认即单例
    	@Bean(initMethod="init",destroyMethod="detory")
    	public Car car(){
    		return new Car();
    	}
    
    }
    

    这样就搞定了,在ioc容器启动的时候,将会把Car这个类加载进容器创建其单例对象。

    那我们主要是观察其初始化和销毁方法

    测试方法:

    	@Test
    	public void test01(){
    		//1、创建ioc容器
    		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class);
    		System.out.println("容器创建完成...");
    		
    		//applicationContext.getBean("car");
    		//关闭容器
    		applicationContext.close();
    	}
    

    打印其输出,

    car constructor...
    car ... init...
    容器创建完成...
    cat...destroy...
    

    小结: bean的生命周期:bean创建---初始化----销毁的过程,

    容器管理bean的生命周期;

    我们可以自定义初始化和销毁方法;

    容器在bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法

    观察上面的结果,也可以发现,在单例模式下,容器启动时则创建单例的car对象,并调用其初始化方法init,当容器要关闭时,执行其销毁方法destroy。

    在多例模式下,这里没测,多例模式下,当我们主动获取对象的时候,容器才会创建bean,类似于一种懒加载机制,另外,在多例模式下,我们观察不到销毁方法的执行,因为多例模式下,spring的ioc不再管理我们自定义的销毁方法。

    二、实现InitializingBean,DisposableBean定义初始化和销毁方法

    InitializingBean接口只有一个抽象方法:

    void afterPropertiesSet() throws Exception;

    DisposableBean接口也只有一个抽象方法

    void destroy() throws Exception;

    我们写一个普通类继承这两个接口 ,

    import org.springframework.beans.factory.DisposableBean;
    import org.springframework.beans.factory.InitializingBean;
    import org.springframework.stereotype.Component;
    
    @Component
    public class Cat implements InitializingBean,DisposableBean {
    	
    	public Cat(){
    		System.out.println("cat constructor...");
    	}
    
    	@Override
    	public void destroy() throws Exception {
    		System.out.println("cat...destroy...");
    	}
    
    	@Override
    	public void afterPropertiesSet() throws Exception {
    		System.out.println("cat...afterPropertiesSet...");
    	}
    }
    
    

    编写一个测试方法,启动ioc容器,测试它的生命周期

    	@Test
    	public void test01(){
    		//1、创建ioc容器
    		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class);
    		System.out.println("容器创建完成...");
    		
    		//applicationContext.getBean("car");
    		//关闭容器
    		applicationContext.close();
    	}
    

    控制台打印:

    cat constructor...
    cat...afterPropertiesSet...
    容器创建完成...
    cat...destroy...
        
    

    从方法名就能看出,在cat这个对象的的属性都被注入之后,就会调用afterPropertiesSet这个方法

    再容器销毁前,会调用Cat类的destroy方法。

    三、通过@PostConstruct和@PreDestroy

    这两个是JSR250规范中的,标注在方法上,也是在对象创建完成属性赋值之后,同样也是在容器销毁之前@PreDestroy标注的方法会被调用

    我们也来举例测试一下,

    创建一个Dog类

    @Component
    public class Dog{
    	public Dog(){
    		System.out.println("dog constructor...");
    	}
    	
    	//对象创建并赋值之后调用
    	@PostConstruct
    	public void init(){
    		System.out.println("Dog....@PostConstruct...");
    	}
    	
    	//容器移除对象之前
    	@PreDestroy
    	public void detory(){
    		System.out.println("Dog....@PreDestroy...");
    	}
    
    }
    
    

    依旧使用上面的测试方法进行测试

    输出结果如下

    dog constructor...
    Dog....@PostConstruct...
    容器创建完成...
    Dog....@PreDestroy...
    

    四、 小结

    以上我们介绍了三种方法对容器中的对象进行初始化和销毁,这只是spring容器中bean生命周期的一小小部分。

    这三种方法可以组合进行使用,即Combining lifecycle mechanisms

    当组合使用时,那这三种方法的执行顺序是什么呢?

    我们不再测试,直接看spring官方文档:

    Multiple lifecycle mechanisms configured for the same bean, with different initialization methods, are called as follows:

    初始化顺序

    • Methods annotated with @PostConstruct
    • afterPropertiesSet() as defined by the InitializingBean callback interface
    • A custom configured init() method

    Destroy methods are called in the same order:

    销毁顺序:

    • Methods annotated with @PreDestroy
    • destroy() as defined by the DisposableBean callback interface
    • A custom configured destroy() method
    你所看得到的天才不过是在你看不到的时候还在努力罢了!
  • 相关阅读:
    gitlab的数据库磁盘坏了已经没有办法恢复情况下如何恢复git上的代码
    psql: FATAL: the database system is in recovery mode
    k8s 下 jenkins 分布式部署:利用pipeline动态增加slave节点
    pipeline 流水线:持续部署(docker)-企业微信群通知消息
    查看私有仓库镜像的版本列表
    MyBatis与Hibernate比较
    MyBatis与JDBC的对比
    Java_Ant详解(转载)
    IntelliJ Idea 常用快捷键列表
    隔行换色
  • 原文地址:https://www.cnblogs.com/heliusKing/p/11385352.html
Copyright © 2020-2023  润新知