作者:我就是在刷粪_944 | 来源:互联网 | 2023-10-11 17:12
1、借用一张BeanFactory中bean的生命周期流程图:
[BeanFactory生命周期流程图]
2、BeanFactory生命周期涉及组件说明:
2.1、InstantiationAwareBeanPostProcessorbean:实例化后置处理器
主要职责:
1、postProcessBeforeInstantiation接口方法就是在bean实例化之前做相应的处理。
2、postProcessAfterInstantiation接口方法就是在bean实例化之后做相应处理。
3、postProcessPropertyValues接口方法就是在bean实例化之后设置bean属性之前做相应处理。
用法:实现InstantiationAwareBeanPostProcessor接口,此处应该注意,InstantiationAwareBeanPostProcessor继承了后面的一个组件BeanPostProcessor接口,如果实现InstantiationAwareBeanPostProcessor此接口就一定也要实现BeanPostProcessor的函数,但是此时bean还没有到BeanPostProcessor函数的处理周期,因此会让人有混淆InstantiationAwareBeanPostProcessor的职责,因此,为了区分开来InstantiationAwareBeanPostProcessor与BeanPostProcessor的职责,spring提供了一个InstantiationAwareBeanPostProcessorAdapter抽象类适配器来区分,因此,我们只需要继承InstantiationAwareBeanPostProcessorAdapter抽象类,重写职责中的三个函数,并且通过工厂的addBeanPostProcessor将其添加到BeanFactory即可。
2.2、BeanNameAware:bean名称设置感知器
主要职责:在设置bean属性值之后提供设置bean name的操作。
用法:需要有设置Bean name 的bean实现此接口重写setBeanName函数即可。
2.3、BeanFactoryAware:bean 工厂实例感知器
主要职责:在BeanNameAware之后让bean 知道自己所在的Bean工厂。
用法:需要知道自己所在的bean 工厂的bean实现此接口重写setBeanFactory函数即可。
2.4、BeanPostProcessor:bean 初始化后置处理器
主要职责:
1、postProcessBeforeInitialization接口方法就是在bean 初始化之前做相应处理。
2、postProcessAfterInitialization接口方法就是在 初始化完成之后做相应处理。
用法:自定义实现BeanPostProcessor接口,然后后通过factory的addBeanPostProcessor将其添加到BeanFactory即可。
2.5、InitializingBean:bean初始化处理器
主要职责:afterPropertiesSet()方法可提供bean初始化功能。
用法:需要提供初始化的bean实现此接口重写afterPropertiesSet()完成自己的业务逻辑。
2.6、的init-method 属性
标签定义的初始化函数属性 ,@PostConstruct只针对ApplicationContext加载的时候才能被处理。
主要职责: 使用xml的方式配置bean的初始化函数,在InitializingBean.afterPropertiesSet()之后 BeanPostProcessor.postProcessAfterInitialization()之前做相应处理。
用法:在需要初始化的bean中定义好初始化函数,然后在中配置在此属性即可。
2.7、DisposableBean:bean销毁处理器
主要职责:在容器销毁bean之前做相应处理。
用法:有需要做bean销毁前做业务处理的bean实现此接口重写destroy()函数可。
2.8、destroy-method属性
标签属性定义bean销毁前处理逻辑,@PreDestroy只针对ApplicationContext加载的时候才能被处理。。
主要职责:在DisposableBean之后bean销毁i前做相应处理。
用法:同init-method属性
2.9、BeanFactory.getBean()流程
Car car = factory.getBean(Car.class);
beanFactory.getBean()触发如下:
1、调用添加的所有InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()方法。
2、实例化bean。
3、调用添加的所有InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()方法。
4、调用添加的所有InstantiationAwareBeanPostProcessor.postProcessPropertyValues()方法。
5、如果bean实现了BeanNameAware接口,调用bean的setBeanName()函数。
6、如果bean实现了BeanFactoryAware接口,调用bean的setBeanFactory()函数。
7、调用添加的所有BeanPostProcessor.postProcessBeforeInitialization()方法。
8、如果bean实现了InitializingBean接口,调用bean的afterPropertiesSet()方法。
9、如果上定义的init-method 属性,则调用bean中的init-method属性值的方法。
10、调用添加的所有BeanPostProcessor.postProcessAfterInitialization()方法。
销毁bean触发如下:
11、如果bean实现了DisposableBean接口,则调用bean中的destroy()方法。
12、如果上定义的destroy-method 属性,则调用bean中的destroy-method属性值的方法。
2.10、BeanFactory.getBean()方法测试结果
getBean触发如下流程测试输出:
1、InstantiationAwareBeanPostProcessor 的 before。。。 每个bean生命周期中都会触发一次
2、Construct... 每个bean生命周期中都会触发一次
3、InstantiationAwareBeanPostProcessor 的 after。。。 每个bean生命周期中都会触发一次
4、InstantiationAwareBeanPostProcessor 的 postProcessPropertyValues。。。 每个bean生命周期中都会触发一次
5、BeanPostProcessor 的 before。。。 每个bean生命周期中都会触发一次
6、InitializingBean 的afterPropertiesSet。。。 bean如果配置了则生命周期中都会触发一次
7、 init-method 属性。。。 bean如果配置了则生命周期中都会触发一次
8、BeanPostProcessor 的 after。。。 每个bean生命周期中都会触发一次
9、DisposableBean 的 destroy。。。 bean如果配置了则生命周期中都会触发一次
10、 destroy-method 属性。。。 bean如果配置了则生命周期中都会触发一次
3、测试代码:
public class Bar implements InitializingBean,DisposableBean {private String price;public Bar() {System.out.println("Construct...");}public String getPrice() { return price;}public void setPrice(String price) {this.price = price;}@Overridepublic void destroy() throws Exception {System.out.println("DisposableBean 的 destroy。。。");}@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("InitializingBean 的afterPropertiesSet。。。");}public void myinit(){ System.out.println(" init-method 属性。。。");}public void mydestroy(){ System.out.println(" destroy-method 属性。。。");}}public class MyInstantiationAwareBeanPostProcessor extendsInstantiationAwareBeanPostProcessorAdapter {@Overridepublic Object postProcessBeforeInstantiation(Class > aClass, String s)throws BeansException {if (s.equals("bar")){System.out.println("InstantiationAwareBeanPostProcessor 的 before。。。");}return null;}@Overridepublic boolean postProcessAfterInstantiation(Object o, String s)throws BeansException {if (s.equals("bar")){System.out.println("InstantiationAwareBeanPostProcessor 的 after。。。");}return false;}@Overridepublic PropertyValues postProcessPropertyValues(PropertyValues propertyValues,PropertyDescriptor[] propertyDescriptors,Object o, String s)throws BeansException {if (s.equals("bar")){System.out.println("InstantiationAwareBeanPostProcessor 的 postProcessPropertyValues。。。");}return propertyValues;}}public class MyBeanPostProcessor implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object o, String s)throws BeansException {if (s.equals("bar")){System.out.println("BeanPostProcessor 的 before。。。");}return o;}@Overridepublic Object postProcessAfterInitialization(Object o, String s)throws BeansException {if (s.equals("bar")){System.out.println("BeanPostProcessor 的 after。。。");}return o;}}测试代码如下:ResourcePatternResolver rpr = new PathMatchingResourcePatternResolver()Resource res = rpr.getResource("classpath:spring-context.xml");DefaultListableBeanFactory factory = new DefaultListableBeanFactory();factory.addBeanPostProcessor(new MyInstantiationAwareBeanPostProcessor());XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);reader.loadBeanDefinitions(res);
BeanFactory 加载完毕,只是注册了所有bean 的 beanDefinition,bean 并没有实例化,这就是第一次惩罚的问题,此处与ApplicationContext有 区别的,ApplicationContext在加载完毕以后就会实例化所有的bean,因为在加载ApplicationContext的时候会给所有的bean相应调一次getBean(),以避免第一次惩罚的问题,延迟加载的bean除外。