spring bean生命周期_Spring源码入门到放弃(八):Bean的生命周期(1)

这节呢,我们来学习下spring bean的生命周期。这部分内容较多,我分成几篇来讲述。

Bean的生命周期流程图

先贴出我自己画的Bean的生命周期流程图

0b0d49bdcc4abf8837882e0e8ce7bda0.png

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

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

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}========测试方法结束=======

注意:

  1. 不要在BeanFactoryPostProcessor实现类中使用beanFactory.getBean()。此时尚未实例化。
  2. 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)就先到这里,下一篇继续讲流程图中的其他内容。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值