这节呢,我们来学习下spring bean的生命周期。这部分内容较多,我分成几篇来讲述。
Bean的生命周期流程图
先贴出我自己画的Bean的生命周期流程图
![0b0d49bdcc4abf8837882e0e8ce7bda0.png](https://i-blog.csdnimg.cn/blog_migrate/8f6d3260bfab4d743b6bf4c9c4eab9c0.jpeg)
Bean的生命周期流程图
若容器注册了以上各种接口,程序那么将会按照以上的流程进行。下面将仔细讲解各接口作用。
加载配置文件
万里长征第一步。Spring需要加载配置文件,就是我们经常说的applicationContext.xml
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
解析配置文件
这一步是为了将配置文件中的等标签信息解析成Spring内部的BeanDefinition对象。
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement{......}
BeanDefinition继承了AttributeAccessor和BeanMetadataElement接口。
- AttributeAccessor:这是一个属性访问者,它提供了访问属性的能力。
public interface AttributeAccessor {void setAttribute(String name, @Nullable Object value);Object getAttribute(String name);Object removeAttribute(String name);boolean hasAttribute(String name);String[] attributeNames();}
- BeanMetadataElement:只有一个方法,用来获取元数据元素的配置源对象:
public interface BeanMetadataElement {Object getSource();}
BeanDefinition接口是Spring对bean的抽象。我们可以看下它包含的方法。
![0ccf6c758fa31121a89cf73cd7158c1b.png](https://i-blog.csdnimg.cn/blog_migrate/92e9dbeb3e956647c9b87dc37d86d19b.jpeg)
BeanDefinition接口
BeanDefinition包含了Bean需要的所有信息,这样Spring就可以利用BeanDefinition生成Bean了。
BeanFactoryPostProcessor和BeanPostProcessor对比
此处我们把这2个接口放在一起介绍。这2个接口很相似,但是有一些区别:
BeanFactoryPostProcessor:可以对bean的定义信息(BeanDefinition)进行处理。也就是说,Spring IoC容器允许BeanFactoryPostProcessor在容器实际 实例化bean之前读取 BeanDefinition 数据,并且可以修改它。比如修改Property或者scope。我们可以配置多个BeanFactoryPostProcessor。你还能 通过设置order属性来控制BeanFactoryPostProcessor的执行次序。 BeanPostProcessor:后置bean处理器后置bean处理器,应用在允许自定义 修改新的bean实例。此时,IOC已经帮我们生成了对应的Bean对象。我们可以配置多个BeanPostProcessor。你还能 通过设置order属性来控制BeanPostProcessor的执行次序。![243a7a55fb9b62cb917d8f98e297da19.png](https://i-blog.csdnimg.cn/blog_migrate/bb1725dc70f5a1371de92db933d6c4e2.jpeg)
BeanFactoryPostProcessor 接口
现在比较流行注解的方式来配置spring,所以我们只保留applicationContext.xml,不再用xml 注册Bean。
- applicationContext.xml
- 实体类
package com.sxdx.entity;import org.springframework.stereotype.Component;//使用注解注入一个名为processor的Bean@Componentpublic class Processor {private String name;private int age;public Processor() {}public Processor(String name, int age) {this.name = name;this.age = age;}//get set...@Overridepublic String toString() {return "Processor{" +"name='" + name + ''' +", age=" + age +'}';}}
- BeanFactoryPostProcessor实现类
@Componentpublic class BeanFactoryPostProcessorOne implements BeanFactoryPostProcessor ,Ordered{@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {System.out.println("BeanFactoryPostProcessorOne");BeanDefinition dog = beanFactory.getBeanDefinition("processor");//通过BeanDefinition修改bean定义信息if (dog != null){MutablePropertyValues mv = dog.getPropertyValues();mv.add("name","拉布拉多").add("age",22);}}@Overridepublic int getOrder() {return 1;}}
@Componentpublic class BeanFactoryPostProcessorTwo implements BeanFactoryPostProcessor , Ordered {@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {System.out.println("BeanFactoryPostProcessorTwo");}@Overridepublic int getOrder() {return 2;}}
BeanFactoryPostProcessorTwo存在的意义主要是验证是否支持排序接口。我们实现了Ordered
- 测试类
public class Test1 {private ApplicationContext applicationContext;@Beforepublic void initXmlBeanFactory() {System.out.println("========测试方法开始=======");applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");}@Afterpublic void after() {System.out.println("========测试方法结束=======");}@Testpublic void test() throws Exception {Processor processor = applicationContext.getBean("processor",Processor.class);System.out.println(processor.toString());}}
- 打印结果:
========测试方法开始=======BeanFactoryPostProcessorOneBeanFactoryPostProcessorTwoProcessor{name='拉布拉多', age=22}========测试方法结束=======
注意:
- 不要在BeanFactoryPostProcessor实现类中使用beanFactory.getBean()。此时尚未实例化。
- BeanFactoryPostProcessorOne在BeanFactoryPostProcessorTwo前执行,说明了BeanFactoryPostProcessor支持排序接口,且数字越小越先执行。
BeanPostProcessor 接口
我们在上面代码的基础上做修改。
- BeanPostProcessor实现类
@Componentpublic class BeanPostProcessorOne implements BeanPostProcessor , Ordered {public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {System.out.println("BeanPostProcessorOne");//获取Bean实例,并修改if (beanName.equals("processor")){((Processor)bean).setAge(100);}return bean;}public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {return bean;}@Overridepublic int getOrder() {return 2;}}
@Componentpublic class BeanPostProcessorTwo implements BeanPostProcessor , Ordered {public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {System.out.println("BeanPostProcessorTwo");return bean;}public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {return bean;}@Overridepublic int getOrder() {return 1;}}
- 测试类
@Testpublic void test() throws Exception {Processor processor = applicationContext.getBean("processor",Processor.class);System.out.println(processor.toString());}
- 测试结果
========测试方法开始=======BeanFactoryPostProcessorOneBeanFactoryPostProcessorTwoBeanPostProcessorTwoBeanPostProcessorOneBeanPostProcessorTwoBeanPostProcessorOneBeanPostProcessorTwoBeanPostProcessorOneProcessor{name='拉布拉多', age=100}========测试方法结束=======
说明:
我们可以看到BeanFactoryPostProcessor先执行,验证了BeanFactoryPostProcessor和BeanPostProcessor的生命周期执行顺序。
BeanPostProcessorTwo在BeanPostProcessorOne前执行,说明了BeanPostProcessor 支持排序接口,且数字越小越先执行。
OK,Bean的生命周期(1)就先到这里,下一篇继续讲流程图中的其他内容。