Spring自带了两种不同的类型的容器。
两种容器的的bean生命周期略有不同
1:bean工厂(由org.springframework.beans.factory.BeanFactory接口定义)是最简单的容器,提供基本的DI 支持。
2:应用上下文(由org.springframework.context.ApplicationContext接口定义),基于BeanFactory构建,
并提供应用框架级别的服务,例如 从属性文件解析文本信息以及发布应用事件给感兴趣的事件监听者。
ApplicationContext Bean生命周期:
1.Spring对bean进行实例化;
2.Spring将值和bean的引用注入到bean对应的属性中;
3.如果bean实现了BeanNameAware接口,Spring将bean的ID传递给setBeanName()方法;
4.如果bean实现了BeanFactoryAware接口,Spring将调用setBeanFactory()方法,将BeanFactory容器实例传入;
5.如果bean实现了ApplicationContextAware接口,Spring将调用setApplicationContext()方法,将bean所在的应用上下文的引用传入进来;
6.如果上下文中存在实现了BeanPostProcessor接口的bean,Spring将调用它们的postProcessBeforeInitialization()方法;
7.如果bean实现了InitializingBean接口,Spring将调用它们的afterPropertiesSet()方法。
8.如果bean使用init-method声明了初始化方法,该方法被调用;
9.如果上下文中存在实现了BeanPostProcessor接口的bean,Spring将调用它们的postProcessAfterInitialization()方法;
经过以上过程之后,就可以正式使用该Bean了,对于scope为singleton的Bean,它们将一直驻留在应用上下文中,直到该应用上下文被销毁;
而对于scope为prototype的Bean,每次被调用都回new一个对象,而且生命周期也交给调用方管理了,不再是Spring容器进行管理了。
10. 容器关闭后,如果Bean实现了DisposableBean接口,则会调用该接口的destroy()方法。
11. 如果Bean配置了destroy-method方法,则会执行destroy-method配置的方法,至此,整个Bean生命周期结束。
BeanFactory Bean生命周期: 与ApplicationContext相比,有如下几点不同:
- BeanFactory容器中,不会调用ApplicationContextAware接口的setApplicationContext()方法。
- BeanPostProcessor接口的postProcessBeforeInitialization方法和postProcessAfterInitialization方法不会自动调用,必须自己通过代码手动注册
- BeanFactory容器启动的时候,不会去实例化所有bean,包括所有scope为singleton且非延迟加载的bean也是一样,而是在调用的时候去实例化。
详细代码参阅:https://github.com/yucong/spring-bean
UserService.java:
package com.yucong.spring.applicationcontext; 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; /** * 该类实现了BeanNameAware,BeanFactoryAware,ApplicationContextAware,InitializingBean, DisposableBean五个接口, * 并且在applicationContext.xml文件中配置了该Bean的id为userService, * 并且配置了init-method和destroy-method,为该Bean配置了属性name为userSercie的值, * 然后定义了一个名为MyBeanPostProcessor的bean, 该bean定义类实现了BeanPostProcessor接口 * * */ public class UserService implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean, DisposableBean { private String name; public UserService() { System.out.println("1.UserService 被实例化,UserService()构造方法"); } public String getName() { return name; } public void setName(String name) { this.name = name; System.out.println("2.注入属性,setName() 被调用"); } public void setBeanName(String beanName) { System.out.println("3.注入beanName,BeanNameAware接口的setBeanName被调用, beanName : " + beanName); } public void setBeanFactory(BeanFactory beanFactory) throws BeansException { System.out.println("4.注入beanFactory,BeanFactoryAware接口的setBeanFactory被调用, beanFactory : " + beanFactory); } public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { System.out.println("5.注入applicationContext,ApplicationContextAware接口的setApplicationContext() 被调用, applicationContext : " + applicationContext); } public void afterPropertiesSet() throws Exception { System.out.println("7.InitializingBean接口afterPropertiesSet() 被调用"); } public void myInit() { System.out.println("8.init-method配置的myInit() 被调用"); } public void destroy() throws Exception { System.out.println("10.DisposableBean接口的destroy() 被调用"); } public void myDestroy() { System.out.println("11.destroy-method配置的myDestroy() 被调用"); } public String toString() { return "UserService[name=" + name + "]"; } }
MyBeanPostProcessor.java
package com.yucong.spring.applicationcontext; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; public class MyBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("9.MyBeanPostProcessor的postProcessAfterInitialization被调用, beanName : "+ beanName); return bean; } /** * 实例化、依赖注入完毕,在调用显式的初始化之前完成一些定制的初始化任务 */ @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("6.MyBeanPostProcessor的postProcessBeforeInitialization被调用, beanName : "+ beanName); return bean; } }
测试类:Test.java
public class Test { public static void main(String[] args) { ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); @SuppressWarnings("unused") UserService userService = (UserService) applicationContext.getBean("userService"); ((ClassPathXmlApplicationContext) applicationContext).close(); } }
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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="userService" class="com.yucong.spring.applicationcontext.UserService" init-method="myInit" destroy-method="myDestroy"> <property name="name" value="张三"></property> </bean> <bean id="myPostProcessor" class="com.yucong.spring.applicationcontext.MyBeanPostProcessor"></bean> </beans>
运行结果:
1.UserService 被实例化,UserService()构造方法
2.注入属性,setName() 被调用
3.注入beanName,BeanNameAware接口的setBeanName被调用, beanName : userService
4.注入beanFactory,BeanFactoryAware接口的setBeanFactory被调用, beanFactory : org.springframework.beans.factory.support.DefaultListableBeanFactory@60addb54: defining beans [userService,myPostProcessor]; root of factory hierarchy
5.注入applicationContext,ApplicationContextAware接口的setApplicationContext() 被调用, applicationContext : org.springframework.context.support.ClassPathXmlApplicationContext@41906a77: startup date [Tue Jul 09 20:02:38 CST 2019]; root of context hierarchy
6.MyBeanPostProcessor的postProcessBeforeInitialization被调用, beanName : userService
7.InitializingBean接口afterPropertiesSet() 被调用
8.init-method配置的myInit() 被调用
9.MyBeanPostProcessor的postProcessAfterInitialization被调用, beanName : userService
10.DisposableBean接口的destroy() 被调用
11.destroy-method配置的myDestroy() 被调用