Spring:BeanDefinition&PostProcessor不了解一下吗?

水稻:这两天看了BeanDefinition和BeanFactoryPostProcessor还有BeanPostProcessor的源码。要不要了解一下

菜瓜:six six six,大佬请讲

水稻:上次我们说SpringIOC容器是一个典型的工厂模式

假如我们把Spring比作一个生产模型的大工厂,那么.class文件就是原材料。而BeanDefinition就是创建模型的模具。不管是传统的XML还是后面的注解,Spring在启动的时候都会创建一个扫描器去扫描指定目录下的.class文件,并根据文件的注解,实现的接口以及成员变量将其封装一个个的BeanDefinition。
    比较重要的属性有id,class,构造函数封装类,属性封装类,factoryMethod等
在对象初始化之前Spring会完成BeanDefinition对象的解析并将其装入List容器beanDefinitionNames中,然后开始遍历该容器并根据BeanDefinition创建对象

菜瓜:sodasinei,BeanDefinition我了解了。它是创建bean的模板,类似于java创建对象依赖的class一样。那还有两个很长的单词是啥呢?

水稻:忽略掉后面老长的后缀,我们看BeanFactory和Bean是不是很亲切。PostProcessor被翻译成后置处理器,暂且我们把它看成是处理器就行

BeanFactory是bean工厂,它可以获取并修改BeanDefinition的属性,进而影响后面创建的对象。
Bean就是Spring的对象,这些个处理器才是真正处理bean对象的各个环节的工序,包括属性,注解,方法

菜瓜:有了模糊的概念,不明觉厉

水稻:来,看demo
复制代码

package com.vip.qc.postprocessor;

import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;

/**

  • 获取初始化好的BeanFactory,此时还未进行bean的实例化

  • @author QuCheng on 2020/6/14.
    */
    @Component
    public class BeanFactoryPostProcessorT implements BeanFactoryPostProcessor {

    public static final String BEAN_NAME = “processorT”;

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    BeanDefinition initializingBeanT = beanFactory.getBeanDefinition(BEAN_NAME);
    MutablePropertyValues propertyValues = initializingBeanT.getPropertyValues();
    String pName = “a”;
    System.out.println(“BeanFactoryPostProcessor a " + propertyValues.getPropertyValue(pName) + " -> 1”);
    propertyValues.addPropertyValue(pName, “1”);
    }
    }
    http://www.sina.com.cn/mid/search.shtml?range=all&c=news&q=%E6%9E%9C%E5%8D%9A%E4%B8%9C%E6%96%B9_18183615678

package com.vip.qc.postprocessor;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

/**

  • @author QuCheng on 2020/6/14.
    */
    @Component
    public class BeanPostProcessorT implements BeanPostProcessor {

    public static final String beanNameT = “processorT”;

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    if (beanNameT.equals(beanName)) {
    ProcessorT processorT = ((ProcessorT) bean);
    System.out.println(“BeanPostProcessor BeforeInitialization a:” + processorT.getA() + “-> 3”);
    processorT.setA(“3”);
    }
    return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    if (beanNameT.equals(beanName)){
    ProcessorT processorT = ((ProcessorT) bean);
    System.out.println(“BeanPostProcessor AfterInitialization a:” + processorT.getA() + “-> 4”);
    processorT.setA(“4”);
    }
    return bean;
    }

}

package com.vip.qc.postprocessor;

import org.springframework.stereotype.Component;

/**

  • @author QuCheng on 2020/6/14.
    */
    @Component
    public class ProcessorT {

    public ProcessorT() {
    System.out.println(“ProcessorT 无参构造 a:” + a + “-> 2” );
    a = “2”;
    }

    private String a;

    public String getA() {
    return a;
    }

    public void setA(String a) {
    this.a = a;
    }

    @Override
    public String toString() {
    return “ProcessorT{” +
    “a=’” + a + ‘’’ +
    ‘}’;
    }
    }

// 测试类
@Test
public void test() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(“com.vip.qc.postprocessor”);
ProcessorT processorT = (ProcessorT) context.getBean(“processorT”);
System.out.println(processorT);
}

// 结果
BeanFactoryPostProcessor a null -> 1
ProcessorT 无参构造 a:null-> 2
BeanPostProcessor BeforeInitialization a:1-> 3
BeanPostProcessor AfterInitialization a:3-> 4
ProcessorT{a=‘4’}

复制代码

BeanFactoryPostProcessor在对象还未初始化前可以拿到对象的BeanDefinition对其设置属性值  
过程中我们分别对属性a设置了1,2,3,4的值。最后我们拿到的值为4

菜瓜:好像看懂了。BeanFactoryPostProcessor可以拿到BeanFactory对象,获取里面所有的BeanDefinition并可对其进行干预。BeanPostProcessor其实是在bean已经被创建完成之后进行加工操作

水稻:没错。这是我们自己进行干预的demo。限于篇幅有限,你可以去看一下Spring自己对于这两个接口的实现源码。比较重要的推荐下面几个
http://www.sina.com.cn/mid/search.shtml?range=all&c=news&q=%E6%96%B0%E6%9E%9C%E5%8D%9A%E4%B8%9C%E6%96%B9_18183615678
ConfigurationClassPostProcessor 实现BeanFactoryPostProcessor子接口
完成对@Configuration、@Component、@ComponentScan、@Bean、@Import、@ImportSource注解的搜集和解析
@Bean注解会被封装成所在Bean的BeanDefinition中的factoryMethod属性中,单独进行实例化
CommonAnnotationBeanPostProcessor 实现 BeanPostProcessor
完成@PostConstruct@PreDestroy@Resource注解的搜集和解析工作
@PostConstruct会在对象初始化且属性渲染完成后进行
@Resource注解(参照下面)
AutowiredAnnotationBeanPostProcessor 实现 BeanPostProcessor
完成@Autowired@Value注解的搜集和解析工作
在对象初始化完成之后会先进行注解的搜集,然后进行属性渲染调用populateBean方法,使用策略模式调用实现接口对注解进行解析,有@Autowired和@Value注解会调用getBean方法发起对依赖属性的注入
AbstractAutoProxyCreator的入口类也是实现的BeanPostProcessor

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值