Spring的BeanFctoryPostProcessor
Last updated
Last updated
概念
BeanFactoryPostProcessor,字面意思就是“Bean工厂之后的处理器”(post可以理解为after),接口如下:
上面的英文的大意是:在bean factory完成标准的初始化之后,对它进行修改。具体时机为:所有的bean definitions都已经加载完成,但是bean还没有进行实例化。通过该方法,可以对Bean的属性进行修改或者添加(eager是与lazy的反义 )。
即BeanFactoryPostProcessor主要是用来在Bean实例化之前(加载完Bean定义之后),修改Bean的属性的,但是并不仅限于此,一切想在实例化Bean之前想做的事情,都可以在这里做。
PropertyResourceConfigurer
负责处理配置文件中的信息,即将配置文件中配置的值解析出来传递给Bean Definition。一般配置Bean的时候,有两种方式,不同的配置方式的具体处理由两个实现类来具体负责。
一是在配置Bean的时候使用占位符,而真正的值写在xxx.properties配置文件中,如:
配置文件config.properties:
这种形式(${...}
)的配置方式,是由PropertyPlaceholderConfigurer来处理的。
二是在配置Bean的时候,设置了默认值,但在配置文件中又重写赋值,如:
配置文件config.properties:
这种形式(beanName.property=value
)的配置方式,是由PropertyOverrideConfigurer来处理的。
此外,PropertyPlaceholderConfigurer除了会用*.properties文件中的参数去替换占位符的内容,还会使用环境变量(System.getProperty(key))中的参数去替换。如果一个参数在配置文件中和系统环境变量中都存在,那么默认会使用*.properties中的参数来替换配置中的占位符,可以使用PropertyPlaceholderConfigurer::systemPropertiesMode来修改这个行为。
PropertySourcesPlaceholderConfigurer
是PropertyPlaceholderConfigurer的升级版,可以额外处理环境Environment和@Value注解中配置信息。也就是它可以根据不同环境来设置来为Bean去加载不同的配置信息。
这些PropertyXxxxConfigurer是BeanFactoryPostProcessor的一类实现或者一类应用,就是去将正确的配置信息设置到Bean Definition中。
CustomScopeConfigurer
从名字来看,它是用来自定义作用域的。Spring默认的作用域有singleton、prototype、request、session、global session。假如这些作用域不符合应用场景,比如想要一个作用域为Thread时(即想要每个线程有一个Bean实例),则可以通过CustomScopeConfigurer来自定义作用域。
上面说到的PropertyXxxxConfigurer负责在BeanFactory创建好之后,在postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)方法,对将要加载或实例化的Bean的Definition传入必要的配置信息。那么自定义作用域为什么也要在这个时机来做呢?
这是因为,Bean的作用域决定了在BeanFactory在getBean的时候到底用什么策略去拿到Bean,是创建实例,还是用原来缓存的等等。比如,我们假如自定义Thread作用域,那么BeanFactory在getBean的时候就需要看当前Thread是不是已经有Bean了,有就直接拿,没有就为当前Thread创建Bean。这个逻辑,需要告知BeanFactory,以便它进行之后的逻辑。
CustomEditorConfigurer
从名字来看,看不出来是edit什么,如果叫CustomPropertyEditorConfigurer就更合适了,其实是对属性进行编辑,即属性编辑配置器(由字符串转换为任意Java类型)。
Spring了已经内置了很多属性编辑器,但是如果不能满足需求,就要使用它来完成。
DeprecatedBeanWarner
对标注了@Deprecated的Bean打出warning日志。
BeanDefinitionRegistryPostProcessor
该接口额外定义了一个方法:所有的常规的BeanDefinition都已经被加载,但是还没有Bean被实例化,所以可以在这里添加更多的BeanDefinition。
ConfigurationClassPostProcessor
它是BeanDefinitionRegistryPostProcessor的实现类,从它的名字叫ConfigurationClass处理器,ConfigurationClass就是标注了@Configuration的class。也就是,它负责从标注了@Configuration的class中解析出BeanDefinition,然后传给BeanDefinitionRegistry。其实,不仅仅是标注了@Configuration的class,它还会解析@Component,@ComponentScan,@Import等注解。
@Service,@Controller,@Repository其实都是@Component 关键逻辑代码:
可以看出,这个类是非常重要的,它解析了我们在class中通过注解定义的Bean。
Spring的BeanFactoryPostProcessor和BeanPostProcessor
Spring源代码分析(4)---BeanFactoryPostProcessor
Spring核心——官配BeanFactoryPostProcessor
浅谈Spring的PropertyPlaceholderConfigurer
Spring Core Container 源码分析五:@Autowired
Spring内部的BeanPostProcessor接口总结