spring 容器中的bean的完整生命周期一共分为十一步完成。
1.bean对象的实例化
2.封装属性,也就是设置properties中的属性值
3.如果bean实现了BeanNameAware,则执行setBeanName方法,也就是bean中的id值
4.如果实现BeanFactoryAware,则执行setBeanFactory()方法
5.如果实现ApplicationContextAware,则执行setApplicationContext()方法
6.如果存在类实现BeanPostProcessor后处理bean,执行postProcessBeforeInitialization,可以在初始化之前执行一些方法(此方法针对所有的bean都生效)
7.如果bean实现了InitializingBean,则执行afterPropertiesSet,执行属性设置之后的操作
8.调用<bean init-method="">执行指定的初始化方法
9.如果存在类实现BeanPostProcessor则执行postProcessAfterInitialization,执行初始化之后的操作(此方法针对所有的bean都生效)
10.执行自身的业务方法
11.如果bean实现了DisposableBean,则执行destory销毁方法
12.调用<bean destory-method="">执行自定义的销毁方法
第六步和第九步可以结合aop,在初始化执行之前或者执行之后执行一些操作。
下面用例子来演示一遍:
1、首先写一个类BeanLifeCircle.java,实现了BeanNameAware, BeanFactoryAware,ApplicationContextAware, InitializingBean, DisposableBean接口,通过set方法注入了name,重写了构造函数,定义了init和destroy方法:
package beanLifeCircle; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; 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 BeanLifeCircle implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean, DisposableBean { private String name; /* 构造函数 */ BeanLifeCircle() { System.out.println("第一步,实例化bean"); } public String getName() { return name; } /* set方法 */ public void setName(String name) { System.out.println("第二步,调用set方法"); this.name = name; } /* 实现BeanNameAware接口的setBeanName方法 */ @Override public void setBeanName(String name) { System.out.println("第三步,setBeanName被调用,调用的id名为:" + name); } /* 实现BeanFactoryAware的setBeanFactory方法 */ @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { System.out.println("第四步,setBeanFactory被调用,beanFactory为:" + beanFactory); } /* 实现ApplicationContextAware的setApplicationContext方法 */ @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { System.out.println("第五步,setApplicationContext被调用,applicationContext为:" + applicationContext); } /* 实现InitializingBean接口的afterPropertiesSet方法 */ @Override public void afterPropertiesSet() throws Exception { System.out.println("第七步,执行afterPropertiesSet方法"); } /* 该方法在spring的xml文件中通过init-method配置 */ public void initMethod() { System.out.println("第八步,执行xml文件中配置的初始化方法init-method"); } /* 实现DisposableBean的destroy方法 */ public void destroy() { System.out.println("第十一步,执行DisposableBean的销毁方法destroy-method"); } /* 该方法在spring的xml文件中通过destroy-method配置 */ public void destroyMethod() { System.out.println("第十二步,执行xml文件中配置的销毁方法destroy-method"); } }
2、编写类MyBeanPostProcessor.java实现BeanPostProcessor接口:
package beanLifeCircle; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; public class MyBeanPostProcessor implements BeanPostProcessor{ /* * 后置处理器的postProcessorBeforeInitailization方法是在bean实例化之后、依赖注入之后、自定义初始化方法init-method之前调用 * (例如:配置文件中bean标签添加init-method属性指定Java类中初始化方法、 * @PostConstruct注解指定初始化方法,Java类实现InitailztingBean接口) */ @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { /* 在这里,能做的事情可就不止上面的这么简单的一句输出了,它还可以过滤每个对象的ip 还可以给所有对象添加属性或者函数,总之就是所有对象! 其实,这里体现了AOP编程的思想,AOP呢就是面向切成编程(针对所有对象编程) */ System.out.println("第六步,postProcessBeforeInitialization方法被调用,beanName=" + beanName); if ("beanLifeCircle".equals(beanName)) {//过滤掉bean实例ID为narCodeService return bean; } System.out.println("后置处理器处理bean=【"+beanName+"】开始,作用类似过滤器"); return bean; } /* * 后置处理器的postProcessorAfterInitailization方法是在bean实例化之后、依赖注入之后、自定义初始化方法init-method之后调用 */ @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("第九步,postProcessAfterInitialization方法被调用"); return bean; } }
3、编写spring配置文件spring-beanLifeCircle.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:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd "> <bean id="beanLifeCircle" class="beanLifeCircle.BeanLifeCircle" init-method="initMethod" destroy-method="destroyMethod"> <property name="name" value="littleBall"></property> </bean> <!--配置自己的后置处理器,优点类似filter--> <bean id="myBeanPostProcessor" class="beanLifeCircle.MyBeanPostProcessor" /> </beans>
4、编写测试类BeanLifeCircleTest.java:
package beanLifeCircle; import org.springframework.context.support.ClassPathXmlApplicationContext; public class BeanLifeCircleTest { public static void main(String[] args) { //加载spring配置,初始化spring容器 ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("classpath:springConfig/spring-beanLifeCircle.xml"); //从spring容器中获取需要的实例化bean BeanLifeCircle beanLifeCircle = (BeanLifeCircle)ac.getBean(BeanLifeCircle.class); //执行业务方法 System.out.println("第十步,执行业务方法" + beanLifeCircle.getName()); //销毁spring容器 ac.destroy(); } }
5、测试结果:
第一步,实例化bean 第二步,调用set方法 第三步,setBeanName被调用,调用的id名为:beanLifeCircle 第四步,setBeanFactory被调用,beanFactory为:org.springframework.beans.factory.support.DefaultListableBeanFactory@36d4b5c: defining beans [beanLifeCircle,myBeanPostProcessor]; root of factory hierarchy 第五步,setApplicationContext被调用,applicationContext为:org.springframework.context.support.ClassPathXmlApplicationContext@6996db8: startup date [Tue Nov 19 16:30:11 CST 2019]; root of context hierarchy 第六步,postProcessBeforeInitialization方法被调用,beanName=beanLifeCircle(此方法针对所有的bean都生效) 第七步,执行afterPropertiesSet方法 第八步,执行xml文件中配置的初始化方法init-method 第九步,postProcessAfterInitialization方法被调用(此方法针对所有的bean都生效) 第十步,执行业务方法littleBall 第十一步,执行DisposableBean的销毁方法destroy-method 第十二步,执行xml文件中配置的销毁方法destroy-method