Spring注解(六):Bean的生命周期中自定义初始化和销毁方法的四种方式

Bean的生命周期指的是Bean从被创建到初始化再被销毁的过程,IOC容器管理Bean的生命周期。在Bean的整个生命周期的过程中的初始化和销毁过程的方法可以被自定义,IOC容器当Bean进行到当前生命周期的时候调用自定义的初始化和销毁方法。在配置文件中可以通过添加init-method和destroy-method指定自定义的初始化和销毁方法,如下:

  <bean id="Person" class="com.xinyi.bean.Person" init-method="" destroy-method="">

在Spring注解开发中有四种自定义初始化和销毁方法。

1)、使用@Bean注解指定初始化和销毁方法

新建一个Fruit类,并自定义初始化和销毁方法,如下:

public class Fruit {

	public Fruit() {
		System.out.println("Fruit被创建");
	}
	
	public void init() {
		System.out.println("Fruit被初始化");
	}
	
	public void destroy() {
		System.out.println("Fruit被销毁");
	}
}

配置类中使用@Bean注解注册组件,并测试

@Configuration
public class MyConfig2 {
	@Bean
	public Fruit fruit() {
		return new Fruit();
	}
}
	//测试声明周期
@Test
	public void test5() {
		//创建ioc容器
		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig2.class);
		System.out.println("IOC容器创建完成");
	}

在这里插入图片描述

在@Bean注解的参数中指定Fruit类自定义的初始化和销毁方法:

	@Bean(initMethod = "init",destroyMethod = "destroy")

在这里插入图片描述
销毁方法只有在IOC容器关闭的时候才调用,所以在测试代码中关闭IOC容器:

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

在这里插入图片描述

所以可以通过@Bean注解参数的initMethod和destroyMethod指定自定义的初始化和销毁的方法。并且初始化方法在对象创建完成后调用,Spring注解(三):@scope设置组件作用域
提到当组件的作用域为单例时在容器启动时即创建对象,而当作用域为原型(PROTOTYPE)时在每次获取对象的时候才创建对象。并且当作用域为原型(PROTOTYPE)时,IOC容器只负责创建Bean但不会管理Bean,所以IOC容器不会调用销毁方法。

2)、Bean实现InitializingBean接口和DisposableBean接口自定义初始化和销毁逻辑

InitializingBean接口源码:

public interface InitializingBean {

	/**
	 * Invoked by the containing {@code BeanFactory} after it has set all bean properties
	 * and satisfied {@link BeanFactoryAware}, {@code ApplicationContextAware} etc.
	 * 

This method allows the bean instance to perform validation of its overall * configuration and final initialization when all bean properties have been set. * @throws Exception in the event of misconfiguration (such as failure to set an * essential property) or if initialization fails for any other reason * Bean都装配完成后执行初始化 */ void afterPropertiesSet() throws Exception;

DisposableBean接口源码:

public interface DisposableBean {

	/**
	 * Invoked by the containing {@code BeanFactory} on destruction of a bean.
	 * @throws Exception in case of shutdown errors. Exceptions will get logged
	 * but not rethrown to allow other beans to release their resources as well.
	 */
	void destroy() throws Exception;

}

public class Fruit01 implements InitializingBean,DisposableBean {
	public void afterPropertiesSet() throws Exception {
		System.out.println("Fruit01初始化");

	}
	public void destroy() throws Exception {
		System.out.println("Fruit01销毁");
	}

	public Fruit01() {
		System.out.println("Fruit01被创建");
	}
}

Spring注解(六):Bean的生命周期中自定义初始化和销毁方法的四种方式_第1张图片
上述就是通过实现InitializingBean接口和DisposableBean接口自定义初始化和销毁逻辑的方法。

3)、使用@PostConstruct(初始化逻辑)和@PreDestroy(销毁逻辑)注解

从Java EE 5规范开始,Servlet中增加了两个影响Servlet生命周期的注解:@PostConstruct和@PreDestroy。
被@PostConstruct修饰的方法会在服务器加载Servlet的时候运行,并且只会被服务器调用一次,类似于Serclet的inti()方法。被@PostConstruct修饰的方法会在构造函数之后,init()方法之前运行。
被@PreDestroy修饰的方法会在服务器卸载Servlet的时候运行,并且只会被服务器调用一次,类似于Servlet的destroy()方法。被@PreDestroy修饰的方法会在destroy()方法之后运行,在Servlet被彻底卸载之前。

public class Fruit02 {
	
	public Fruit02() {
		System.out.println("Fruit02创建");
	}
	
	//对象创建并赋值之后调用
	@PostConstruct
	public void init() {
		System.out.println("Fruit02初始化");
	}
	
	//对象被从ioc容器中移除之前调用
	@PreDestroy
	public void destroy() {
		System.out.println("Fruit02被销毁");
	}
}

在这里插入图片描述

4)、使用BeanPostProcessor接口

BeanPostProcessor又叫Bean的后置处理器,是Spring框架中IOC容器提供的一个扩展接口,在Bean初始化的前后进行一些处理工作。BeanPostProcessor的源码如下:

public interface BeanPostProcessor {

	/**
	 * Apply this BeanPostProcessor to the given new bean instance before any bean
	 * initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
	 * or a custom init-method). The bean will already be populated with property values.
	 * The returned bean instance may be a wrapper around the original.
	 * 

The default implementation returns the given {@code bean} as-is. * @param bean the new bean instance * @param beanName the name of the bean * @return the bean instance to use, either the original or a wrapped one; * if {@code null}, no subsequent BeanPostProcessors will be invoked * @throws org.springframework.beans.BeansException in case of errors * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet */ @Nullable //bean初始化方法调用前被调用 default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return bean; } /** * Apply this BeanPostProcessor to the given new bean instance after any bean * initialization callbacks (like InitializingBean's {@code afterPropertiesSet} * or a custom init-method). The bean will already be populated with property values. * The returned bean instance may be a wrapper around the original. *

In case of a FactoryBean, this callback will be invoked for both the FactoryBean * instance and the objects created by the FactoryBean (as of Spring 2.0). The * post-processor can decide whether to apply to either the FactoryBean or created * objects or both through corresponding {@code bean instanceof FactoryBean} checks. *

This callback will also be invoked after a short-circuiting triggered by a * {@link InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation} method, * in contrast to all other BeanPostProcessor callbacks. *

The default implementation returns the given {@code bean} as-is. * @param bean the new bean instance * @param beanName the name of the bean * @return the bean instance to use, either the original or a wrapped one; * if {@code null}, no subsequent BeanPostProcessors will be invoked * @throws org.springframework.beans.BeansException in case of errors * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet * @see org.springframework.beans.factory.FactoryBean */ @Nullable //bean初始化方法调用后被调用 default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; }

public class MyBeanPostProcessor implements BeanPostProcessor{

    //bean初始化方法调用前被调用
    public Object postProcessBeforeInitialization(Object bean, String beanName) {
    	System.out.println("postProcessBeforeInitialization..."+beanName+"=>"+bean);
		return bean;
    }
    //bean初始化方法调用后被调用
    public Object postProcessAfterInitialization(Object bean, String beanName) {
    	System.out.println("postProcessAfterInitialization..."+beanName+"=>"+bean);
		return bean;
    }

}

Spring注解(六):Bean的生命周期中自定义初始化和销毁方法的四种方式_第2张图片
通过上述运行结果可以发现使用BeanPostProcessor的运行顺序为:
IOC容器实例化Bean---->
调用BeanPostProcessor的postProcessBeforeInitialization方法---->
调用bean实例的初始化方法---->
调用BeanPostProcessor的postProcessAfterInitialization方法

以上就是Bean的生命周期过程中自定义初始化喝销毁方法的四种方式。
Spring注解(六):Bean的生命周期中自定义初始化和销毁方法的四种方式_第3张图片

你可能感兴趣的:(spring,Java,笔试面试题,spring,注解,bean声明周期,销毁,初始化)