说到Bean的生命周期,不得不先提两个关键的接口:
BeanFactory 和ApplicationContext:前者我们称之为IOC容器,后者则称之为设备上下文.BeanFactory好比Spring的心脏,而ApplicationContext在BeanFactory的基础上完善了Spring,使之成为一个整体
ApplicationContext是BeanFactory的子接口
具体了解生命周期之前先看下BeanFactory 的相关4大接口:
1.本身:BeanFactory:
子类:
ListableBeanFactory :定义了访问bean 信息的接口
HierachicalBeanFactory: 定义了子容器向父容器访问的接口
ConfigurableBeanFactory:重要的子类,定义了类装载器,属性编辑器,容器初始化后置处理器等
2.AutowireCapableBeanFactory:
使得容器可以以某种匹配方式(名称or 类型) 的方式 进行自动装配
3.SingletonBeanRegistry:
定义了运行期间可以向容器注册单实例bean的方法
4.BeanDefinitionRegistry:
在Spring容器中,bean都是以BeanDefinition的形式存在的,这个顶级接口提供了向容器手工注册bean的方法
在BeanFactory中bean的生命周期又是:
当调用getBean()
1.调用InstantationAwareBeanPostProcessor的postProcessBeforeInstantation方法
2.实例化bean
3.调用InstantationAwareBeanPostProcessor的postProcessAfterInstantation方法
4.尝试设置属性:调用InstantationAwareBeanPostProcessor的postProcessPropertyValues-
5.设置属性
6.调用beanNameAware的setBeanName方法
7.调用BeanFactoryAware的setBeanFacotroy方法
8.之后初始化: 先调用BeanPostProcessor的postProcessBeforeInitializing()
9.初始化,调用<init-method>指定的方法,或者是@PostConstruct方法
10.调用InitializingBean的afterPropertySet()方法
11.调用BeanPostProcessor的postProcessAfterInitializaiton()方法
如果bean是prototype型的,则直接返回这个bean
如果是singleton型的,则加入到Spring的缓存池中,下次调用直接从缓存池中取得
ApplicationContext
与BeanFactory类似,但是不同之处在于BeanFactory是首次调用的时候才初始化bean,而ApplicationContext是启动既加载所有的Bean(lazy-init的除外),并且如果Bean实现了ApplcationContextAware借口,则还会调用setApplicaitonContext方法,并且ApplicationContext多了工厂后处理器:BeanFactoryPostProcessor
大致流程:
1.当容器启动的时候,容器会将所有需要注册的bean 都建立一个对应的beanDefinition ,然后注册到beanDefinitionRegistry中
2.容器从BeanDefinitionRegistry中找出所有实现了BeanFactoryPostProcessor的借口的bean,对beanDefinition进行后处理
3.重复上面的1-7
4.如果实现了ApplicationContext接口,则调用setApplicationContext
5.重复上面 8-11
有许多相同的步骤,因为本来ApplicationContext就是BeanFactory的一个子接口;Spring中这么多的接口使得Bean的共性与个性得以区分:
Bean级接口:BeanNameAware,BeanFactoryAware,ApplicationContextAware,InitializingBean,DisposableBean
容器级接口:BeanFactoryPostProcessor,InstantationAwareBeanPostProcessor,BeanPostProcessor
共性由容器级接口设置,个性由各自的Bean级接口设置
具体的代码演示:
public class Car implements BeanNameAware,BeanFactoryAware,InitializingBean{
private String brand;
private Double speed;
private String beanName;
private BeanFactory beanFactory;
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public Double getSpeed() {
return speed;
}
public void setSpeed(Double speed) {
this.speed = speed;
}
public String getBeanName() {
return beanName;
}
public BeanFactory getBeanFactory() {
return beanFactory;
}
public void setBeanFactory(BeanFactory arg0) throws BeansException {
System.out.println("第四步:设置beanFactory");
this.beanFactory=arg0;
}
public void setBeanName(String arg0) {
System.out.println("第三步:设置beanName");
this.beanName=arg0;
}
public void postConstruct()
{
System.out.println("第七步:在构造函数执行之前执行");
}
public void preDestory()
{
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("第六步:afterPropertySet");
}
}
InstantationBeanPostProcessor
public class MyInstantationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter{
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
System.out.println("第二步:当bean实例化之后会调用这个方法");
return super.postProcessAfterInstantiation(bean, beanName);
}
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
System.out.println("第一步:当讲bean的信息存放到BeanDefinitionRegistry之后第一步会调用这个");
return super.postProcessBeforeInstantiation(beanClass, beanName);
}
}
BeanPostProcessor
public class MyBeanPostProcessor implements BeanPostProcessor{
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("第五步:在初始化bean之前执行");
return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
}
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("第八步:在初始化bean之后执行");
return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
}
}
启动类:
因为是BeanFactory,所以是需要手动添加postProcessor的,但是注意当有多个postProcessor的时候,请将各个实现类都实现order接口,预定好顺序
public class TestBeanFactory {
@Test
public void test1()
{
Resource resouce=new ClassPathResource("beanFactoryTest.xml");
DefaultListableBeanFactory beanFactor=new DefaultListableBeanFactory();
BeanDefinitionReader reader=new XmlBeanDefinitionReader(beanFactor);
reader.loadBeanDefinitions(resouce);
beanFactor.addBeanPostProcessor(new MyBeanPostProcessor());
beanFactor.addBeanPostProcessor(new MyInstantationBeanPostProcessor());
beanFactor.getBean("car");
}
}