文章目录

  • 一、通过@Bean注解指定初始化和销毁方法
  • 二、让Bean实现InitializingBean和DisposableBean接口
  • 三、使用JSR-250规范中的@PostConstruct和@PreDestroy注解
  • 四、BeanPostProcessor处理初始化前后的工作


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

在初始化和销毁方法前后进行处理的方式:(初始化方法都是在属性赋值后执行,销毁方法是在移除bean或关闭容器时执行)
1.在@Bean注解中使用init-method属性和destroy-method属性,自定义初始化、销毁时的逻辑。
2.让bean实现InitializingBean和DisposableBean接口。
afterPropertiesSet:创建完bean实例,并且赋值完属性后进行调用
destroy:会在容器关闭的时候进行调用
3.使用JSR-250规范中的@PostConstruct和@PreDestroy注解。(这2个注解标注的方法不能带参数)
4.让bean实现BeanPostProcessor接口(bean的后置处理器),在初始化前后进行处理工作。
postProcessBeforeInitialization:在初始化之前工作(即在afterPropertiesSet、@PostConstruct、init-method之前调用)
postProcessAfterInitialization:在初始化之后工作(即在afterPropertiesSet、@PostConstruct、init-method之后调用)

初始化和销毁方法的使用场景:
在配置数据源时,初始化会对很多的数据源的属性进行赋值操作。
在销毁的时候,需要对数据源的连接等信息进行关闭和清理。

@Component
public class Car {
	
	public Car(){
		System.out.println("car constructor...");
	}
	
	// 这里的init()方法和destroy()方法必须是无参方法
	public void init(){
		System.out.println("car ... init...");
	}
	
	// bean的销毁方法是在容器关闭的时候被调用的
	public void detory(){
		System.out.println("car ... detory...");
	}

}
@ComponentScan("com.lwk.bean")
@Configuration
public class MainConfigOfLifeCycle {
	// 在@Bean注解中使用init-method属性和destroy-method属性
    @Bean(initMethod="init", destroyMethod="destroy")
   //@Scope("prototype") 
    public Car car() { return new Car();}
}
public class IOCTest_LifeCycle {
	
	@Test
	public void test01() {
		// 1. 创建IOC容器
		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class);
		System.out.println("容器创建完成");
		
		// applicationContext.getBean("car"); // 多实例bean在获取的时候才创建对象		

		// 关闭容器
		applicationContext.close();
	}

}
  • bean对象的初始化方法调用的时机:对象创建完成,如果对象中存在一些属性,并且这些属性也都赋好值之后,那么就会调用bean的初始化方法。对于单实例bean来说,在Spring容器创建完成后,Spring容器会自动调用bean的初始化方法;对于多实例bean来说,在每次获取bean对象的时候,调用bean的初始化方法。
  • bean对象的销毁方法调用的时机:对于单实例bean来说,在容器关闭的时候,会调用bean的销毁方法;对于多实例bean来说,Spring容器不会管理这个bean,也就不会自动调用这个bean的销毁方法了。不过,可以手动调用多实例bean的销毁方法。

二、让Bean实现InitializingBean和DisposableBean接口

/**
 * 多实例bean的生命周期不归Spring容器来管理,这里的DisposableBean接口中的方法是由Spring容器来调用的,
 * 所以如果一个多实例bean实现了DisposableBean接口是没有意义的,因为相应的方法根本不会被调用
 */
@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...");
    }

    // 创建完bean实例,并且赋值完属性后进行调用
    @Override
    public void afterPropertiesSet() throws Exception { 
   		System.out.println("cat afterPropertiesSet...");
    }
}

三、使用JSR-250规范中的@PostConstruct和@PreDestroy注解

@Component
public class Dog {
    private ApplicationContext applicationContext;

    public Dog() {System.out.println("dog constructor...");}
    
    // 对象创建并赋值之后调用
    @PostConstruct
    public void init() {System.out.println("dog...@PostConstruct...");}

    // 在容器销毁(移除)bean之前调用
    @PreDestroy
    public void destory() {System.out.println("dog...@PreDestroy...");}

}

四、BeanPostProcessor处理初始化前后的工作

/**
 * 后置处理器:初始化前后进行处理工作
 * 将后置处理器加入到容器中
 */
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {

	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		System.out.println("postProcessBeforeInitialization..."+beanName+"=>"+bean);
		return bean;
	}

	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		System.out.println("postProcessAfterInitialization..."+beanName+"=>"+bean);
		return bean;
	}

}