Spring IoC容器的本质就是为了管理Bean。对于Bean而言,在容器中存在其生命周期,它的初始化和销毁也需要一个过程,在一些需要自定义的过程中,我们可以插入代码去改变它们的一些行为,以满足特定的需求,这就需要使用到Spring Bean的生命周期了。
生命周期主要是为了了解Spring IoC容器初始化的和销毁Bean的过程。
Spring IoC容器对Bean的管理还是比较复杂的,Spring IoC容器在执行了初始化和依赖注入后,会执行一定的步骤来完成初始化,通过这些步骤我们就能自定义初始化,而在Spring IoC容器正常关闭的时候,它会也执行一定的步骤来关闭容器,释放资源。除需要了解整个生命周期的步骤外,还要知道这些生命周期的接口是针对什么而言的。
首先介绍生命周期的步骤:
- instantiate bean对象实例化
- populate properties封装属性
- 如果Bean实现了接口 BeanNameAware 的 setBeanName 方法,那么它就会调用这个方法
- 如果Bean实现了接口 BeanFactoryAware 的 setBeanName方法,那么它就会调用这个方法
- 如果Bean实现了接口 ApplicationContextAware 的 setApplicationContext 方法,且Spring IoC容器也必须是一个ApplicationContext 接口的实现类,那么才会调用这个方法,否则是不调用的
- 如果Bean实现了接口 BeanPostProcessor 的 postProcessBeforeInitialization 方法,那么它就会调用这个方法
- 如果Bean实现了接口 BeanFactoryProcessor 的 afterPropertiesSet 方法,那么它就会调用这个方法
- 如果Bean自定义了初始化方法<bean init-method=" " >,它就会调用已定义的初始化方法
- 如果Bean实现了接口 BeanPostProcessor 的 postProcessAfterInitialization 方法,完成了这些调用,这个时候就完成了初始化,那么Bean就存在Spring IoC的容器中了 ,使用者就可以从中获取Bean的服务
- 如果Bean实现了接口 DisposableBean 的 destory 方法,那么就会调用它。
- 如果定义了自定义销毁方法<bean destory-method=" ">,那么就会调用它
测试例子:
创建类Man
package com.ioc.demo3;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class Man implements BeanNameAware, ApplicationContextAware, InitializingBean, DisposableBean {
private String name;
public void setName(String name) {
System.out.println("第二步:设置属性");
this.name = name;
}
public Man(){
System.out.println("第一步:初始化。。。");
}
public void setup(){
System.out.println("第七步:Man被初始化了。。。");
}
public void teardown(){
System.out.println("第十一步骤:Man被销毁了。。。");
}
@Override
public void setBeanName(String name) {
System.out.println("第三步:设置Bean的名称name");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("第四步:了解工厂信息");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("第六步:属性设置后");
}
public void run(){
System.out.println("第九步:执行业务方法");
}
@Override
public void destroy() throws Exception {
System.out.println("第十步:执行Spring的销毁方法");
}
}
创建类MyBeanPostProcessor
package com.ioc.demo3;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("第五步:初始化前的方法..");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("第八步:初始化后的方法。。");
return bean;
}
}
设置applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<bean id="man" class="com.ioc.demo3.Man" init-method="setup" destroy-method="teardown">
<property name="name" value="小刘"></property>
</bean>
<bean class="com.ioc.demo3.MyBeanPostProcessor"/>
</beans>
测试类
package com.ioc.demo3;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringDemo3 {
@Test
public void demo(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
Man man1 = (Man)applicationContext.getBean("man");
man1.run();
((ClassPathXmlApplicationContext) applicationContext).close();
}
}
运行结果: