欧博官网:Spring:BeanDefinition&PostProcessor不领会一下吗?

admin 4周前 (09-30) 科技 57 1

水稻:这两天看了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");
    }
}


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自己对于这两个接口的实现源码。对照主要的推荐下面几个

  • 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

菜瓜:你放心,我不会看的。这么庞大的器械,听着都费劲

水稻:不愧是你!没事,有机遇聊bean的生命周期的时刻咱们还会说到这些器械。到时刻再刷一遍

 

,

联博API接口

www.326681.com采用以太坊区块链高度哈希值作为统计数据,联博以太坊统计数据开源、公平、无任何作弊可能性。联博统计免费提供API接口,支持多语言接入。

Allbet声明:该文看法仅代表作者自己,与本平台无关。转载请注明:欧博官网:Spring:BeanDefinition&PostProcessor不领会一下吗?

网友评论

  • (*)

最新评论

  • 联博以太坊 2020-09-30 00:13:11 回复

    欧博电脑版欢迎进入欧博电脑版(Allbet Game):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。留下脚印

    1

文章归档

站点信息

  • 文章总数:480
  • 页面总数:0
  • 分类总数:8
  • 标签总数:948
  • 评论总数:151
  • 浏览总数:5598