聊一聊SpringBean的生命周期——创建、初始化、销毁。

Bean的生命周期是指Bean的创建、初始化、销毁的过程。Bean的生命周期是由Spring的Ioc容器进行管理的。

关于Bean的创建详细过程请看我之前的文章:Spring注入Bean的四种方式,看这一篇就够了

首先从Spring的角度去看对Bean的创建、初始化和销毁过程。

创建:对Bean的属性成员进行赋值、封装对象。

初始化:后置处理器执行(初始化方法前后进行处理)。

销毁:执行销毁方法,对单例Bean容器进行清理。多实例的bean,容器只负责初始化, 但不会管理bean, 容器关闭时不会调用销毁方法。

从面的三个过程中出现了初始化方法销毁方法,这两个方法是可以自定义的。共有三种方法,分别结合代码熟悉一下。

1、通过@Bean注解指定。

Config配置类:指明initMethod和destroyMethod的值

...

//init和destroy分别是自定义的初始化和销毁方法
@Bean(initMethod="init", destroyMethod="destory")
public Bike bike(){
	return new Bike();
}

...

Bike类:自定义方法与initMethod和destroyMethod的值相对应

public class Bike {
    //构造器
	public Bike(){
		System.out.println("Bike constructor..............");
	}

    //初始化
	public void init(){
		System.out.println("Bike .....init.....");
	}

    //销毁
	public void destory(){
		System.out.println("Bike.....destory");
	}
}

2、实现Spring提供的接口 InitializingBean, DisposableBean

从代码看需要实现这两个接口的两个方法:

//初始化(设置属性值之后)
void afterPropertiesSet() throws Exception;

//销毁
void destroy() throws Exception;

Bike类:需要使用@Component注解使之成为Spring组件

package com.csdn.asong.bean;

@Component
public class Bike implements InitializingBean, DisposableBean{

	public Bike(){
		System.out.println("Bike......constructor............");
	}
	//当我们bean销毁时,调用此方法
	@Override
	public void destroy() throws Exception {
		System.out.println("Bike......destory......");
		//logger.error
	}
	//当我们的bean属性赋值和初始化完成时调用
	@Override
	public void afterPropertiesSet() throws Exception {
		System.out.println("Bike.......afterPropertiesSet()...");
		
	}

}

同时配置类要加ComponentScan注解,扫描当前类所在的包

@ComponentScan("com.csdn.asong")

3、实现JSR250规范,这个规范是Spring提供的,需要在初始化和销毁方法上添加@PostConstruct和@PreDestroy注解

package com.csdn.asong.bean;

@Component
public class Bike {
	public Bike(){
		System.out.println("Bike.....constructor........");
	}

    //创建完成,赋值后进行初始化
	@PostConstruct
	public void init(){
		System.out.println("Bike.....@PostConstruct........");
	}
	
    //销毁
	@PreDestroy
	public void destory(){
		System.out.println("Bike.....@PreDestroy......");
	}
}

同时配置类要加ComponentScan注解,扫描当前类所在的包

 

除了以上自定义的初始化方法外,Spring提供了后置处理器(BeanPostProcessor接口)对初始化方法进行增强,并且会对每个 bean对象的初始化方法进行增强

public interface BeanPostProcessor {

    //初始化方法之前执行
	@Nullable
	default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

    //初始化方法之后执行
	@Nullable
	default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

}

实现:同样需要@Component注解

package com.csdn.asong.bean;

@Component
public class CustomBeanPostProcessor implements BeanPostProcessor{
	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		//返回一个的对象(传过来的对象)
		//在初始化方法调用之前进行后置处理工作,
		//什么时候调用它: init-method=init之前调用
		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;
	}
}

对于非懒加载单例Bean,测试一下构造器、初始化方法、销毁方法、后置处理器方法的执行过程。(多例Bean和懒加载单例Bean使用的时候创建,不做讨论)

测试类:

public class Test {
	@Test
	public void test01(){
		AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class);
		
		System.out.println("IOC容器创建完成........");
		app.close();
		
	}
}

 

配置类:

@ComponentScan("com.csdn.asong.bean")
@Configuration
public class 、MainConfigOfLifeCycle {

	@Bean(initMethod="init", destroyMethod="destory")
	public Bike bike(){
		return new Bike();
	}
	
}

控制台输出:

...
Bike constructor..............
postProcessBeforeInitialization....bike...com.csdn.bean.bean.Bike@6193932a
Bike .....init.....
postProcessAfterInitialization....bike...com.csdn.bean.bean.Bike@6193932a
IOC容器创建完成........
Bike.....destory
...

可以看到执行过程为:构造器、后置处理器(前置方法)、初始化方法、后置处理器(后置方法)、销毁方法。

在初始化的过程中有一步骤是invokeAwareMethods(beanName, bean); 表示调用Aware方法。Aware是指感知,Bean可以实现Aware相关接口,并且对应的后置处理器会把相应的组件注入。例如:我的 Bike 需要获取对应的容器上下文,那么它需要实现ApplicationContextAware,要看一下相关Aware源码,是需要实setApplicationContext方法。

此时的Bike

public class Bike implements ApplicationContextAware {
	//Spring容器上下文。由相应后置处理器注入
	private ApplicationContext applicationContext;
	
	public Bike(){
		System.out.println("Bike constructor..............");
	}
	public void init(){
		System.out.println("Bike .....init.....");
	}
	public void destory(){
		System.out.println("Bike.....destory");
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		this.applicationContext = applicationContext;
	}
}

那么这样在初始化Bean的时候,Spring的后置处理器 ApplicationContextAwareProcessor 就会在初始化的时候(初始化方法前)把Spring容器上下文通过set方法注入到Bike。为什么是init方法之前?因为这个后置处理器是BeanPostProcessor接口的实现类,但只实现了postProcessBeforeInitialization这个方法。

 

BeanPostProcessor是一个非常强大的接口,贯穿整个容器,下次有空再结合代码聊一聊。

 

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