BeanFactoryPostProcessor
# BeanFactoryPostProcessor
# 概述
# 源码分析
# AbstractApplicationContext$invokeBeanFactoryPostProcessors()
在Spring容器启动时的核心方法reflesh()的流程中,有一个invokeBeanFactoryPostProcessors()方法
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
其中getBeanFactoryPostProcessors():获取容器上下文中已经注册的BeanFactoryPostProcessor。
所以这里把容器中已注册的BeanFactoryPostProcessor和当前beanFactory实例传进去,接下来调用BeanFactoryPostProcessor
# PostProcessorRegistrationDelegate$invokeBeanFactoryPostProcessors
下面来看看方法PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors()的实现
- 判断参数beanFactory是BeanDefinitionRegistry类型:
- 先创建两个集合,分别存储普通的BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor接口的子接口
BeanFactoryPostProcessor$postProcessBeanFactory:主要用来在Bean被实例化之前,修改Bean工厂
BeanDefinitionRegistryPostProcessor$postProcessBeanDefinitionRegistry:主要用来在Bean被实例化前,修改Bean定义信息。比如Mybatis的实现就依赖它
在整个执行Bean工厂后置处理器的过程中,BeanDefinitionRegistryPostProcessor的顺序优先于BeanFactoryPostProcessor
- 把BeanDefinitionRegistryPostProcessor 与 beanFactoryPostProcessors区分开
// BeanDefinitionRegistryPostProcessor 与 beanFactoryPostProcessors区分开
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
// 直接执行
// 这里执行了为什么还要添加到集合中后面执行
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {
regularPostProcessors.add(postProcessor);
}
}
- 首先调用实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
先从工厂中,按类型查找所有BeanDefinitionRegistryPostProcessor实现类对应的类名,判断是否实现了接口PriorityOrdered
根据类名,获取bean实例
对处理器排序
把这些处理器添加到保存postProcessBeanDefinitionRegistry的集合中,方便后面调用
最后调用当前这些后置处理器
- 然后调用实现了Ordered接口的BeanDefinitionRegistryPostProcessor
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
整体流程与上面一致,这里重新查找了一遍,是因为上面的流程处理完,可能会新增processor
- 最后调用其他BeanDefinitionRegistryPostProcessors,直到没有查找到新的processor出现
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}
- 然后调用集合中保存的两种processor
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
- 如果参数beanFactory不是BeanDefinitionRegistry类型,则直接调用入参的beanFactoryPostProcessors
else {
// Invoke factory processors registered with the context instance.
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
- 至此,入参中的beanFactoryPostProcessors已经全部执行,接下来查找容器中所有实现了beanFactoryPostProcessors接口的类,进行调用
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
}
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// Finally, invoke all other BeanFactoryPostProcessors.
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
同样会按照实现了PriorityOrdered、Ordered和其他没有实现排序接口的顺序
# 常用BeanFactoryPostProcessor
# ConfigurationClassPostProcessor
# 概述
可以扫描@ComponentScan @Bean @Import @ImportResource
# 源码分析
# MapperScannerConfigurer
可以扫描@MapperScanner
package com.prac.springbootdemo.bean_factory_post_processor;
import com.alibaba.druid.pool.DruidDataSource;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.GenericApplicationContext;
import javax.sql.DataSource;
import java.io.IOException;
/**
* 2022/6/4
*/
public class BeanFactoryPostProcessorTests {
public static void main(String[] args) throws IOException {
GenericApplicationContext context = new GenericApplicationContext();
context.registerBean("Config", Config.class);
// @ComponentScan @Bean @Import @ImportResource
// context.registerBean(ConfigurationClassPostProcessor.class);
// @MapperScanner
// context.registerBean(MapperScannerConfigurer.class, bd -> {
// bd.getPropertyValues().add("basePackage", "com.prac.springbootdemo.bean_factory_post_processor.mapper");
// });
// 自己实现组件扫描 抽取出一个类
// context.registerBean(ComponentScanPostProcessor.class);
// 自己实现@Bean
context.registerBean(BeanScanPostProcessor.class);
// 实现Mapper扫描
context.registerBean(MapperScanPostProcessor.class);
context.refresh();
for (String name : context.getBeanDefinitionNames()) {
System.out.println("容器里bean: "+ name);
}
}
/**
* 2022/6/4
*/
@Configuration
@ComponentScan("com.prac.springbootdemo.bean_factory_post_processor.compoent")
public static class Config {
@Bean
public Bean1 bean1() {
return new Bean1();
}
@Bean
public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource) {
SqlSessionFactoryBean sqlsessionFactoryBean = new SqlSessionFactoryBean();
sqlsessionFactoryBean.setDataSource(dataSource);
return sqlsessionFactoryBean;
}
@Bean(initMethod = "init")
public DruidDataSource dataSource() {
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setUrl("jdbc:mysql://120.79.93.88:3306");
druidDataSource.setUsername("root");
druidDataSource.setPassword("root");
return druidDataSource;
}
// /**
// * spring并不能管理接口 所以需要工厂来根据接口生产bean
// * 这样一个个可以实现,但是没法批量添加包下所有mapper接口
// * @param sqlSessionFactory
// * @return
// */
// @Bean
// public MapperFactoryBean<Mapper1> mapper1(SqlSessionFactory sqlSessionFactory){
// MapperFactoryBean<Mapper1> factory = new MapperFactoryBean<>(Mapper1.class);
// factory.setSqlSessionFactory(sqlSessionFactory);
// return factory;
// }
//
// @Bean
// public MapperFactoryBean<Mapper2> mapper2(SqlSessionFactory sqlSessionFactory){
// MapperFactoryBean<Mapper2> factory = new MapperFactoryBean<>(Mapper2.class);
// factory.setSqlSessionFactory(sqlSessionFactory);
// return factory;
// }
}
public static class Bean1 {
public Bean1() {
System.out.println("bean1 init");
}
}
}
package com.prac.springbootdemo.bean_factory_post_processor.compoent;
import org.springframework.stereotype.Component;
/**
* 2022/6/4
*/
@Component
public class Bean2 {
public Bean2() {
System.out.println("bean2 init");
}
}
package com.prac.springbootdemo.bean_factory_post_processor.mapper;
import org.apache.ibatis.annotations.Mapper;
/**
* 2022/6/4
*/
@Mapper
public interface Mapper1 {
}
package com.prac.springbootdemo.bean_factory_post_processor.mapper;
import org.apache.ibatis.annotations.Mapper;
/**
* 2022/6/4
*/
@Mapper
public interface Mapper2 {
}
# 自己实现BeanFactoryPostProcessor
# 自己实现@Component扫描
public class ComponentScanPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) {
try {
ComponentScan componentScan = AnnotationUtils.findAnnotation(BeanFactoryPostProcessorTests.Config.class, ComponentScan.class);
CachingMetadataReaderFactory cachingMetadataReaderFactory = new CachingMetadataReaderFactory();
AnnotationBeanNameGenerator generator = new AnnotationBeanNameGenerator();
if (componentScan != null){
for (String p : componentScan.basePackages()) {
String path = "classpath*:" + p.replace(".", "/") + "/**/*.class";
Resource[] resources = new PathMatchingResourcePatternResolver().getResources(path);
for (Resource resource : resources) {
MetadataReader reader = cachingMetadataReaderFactory.getMetadataReader(resource);
AnnotationMetadata annotationMetadata = reader.getAnnotationMetadata();
if (annotationMetadata.hasAnnotation(Component.class.getName()) ||
annotationMetadata.hasMetaAnnotation(Component.class.getName())){
// 获取bean定义信息
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder
.genericBeanDefinition(reader.getClassMetadata().getClassName())
.getBeanDefinition();
if (configurableListableBeanFactory instanceof DefaultListableBeanFactory){
DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) configurableListableBeanFactory;
String beanName = generator.generateBeanName(beanDefinition, beanFactory);
// 注册bean
beanFactory.registerBeanDefinition(beanName,beanDefinition);
}
}
}
}
}
}catch (Exception e){
}
}
}
# 自己实现扫描@Bean
- 可以一个个定义
// /**
// * spring并不能管理接口 所以需要工厂来根据接口生产bean
// * 这样一个个可以实现,但是没法批量添加包下所有mapper接口
// * @param sqlSessionFactory
// * @return
// */
// @Bean
// public MapperFactoryBean<Mapper1> mapper1(SqlSessionFactory sqlSessionFactory){
// MapperFactoryBean<Mapper1> factory = new MapperFactoryBean<>(Mapper1.class);
// factory.setSqlSessionFactory(sqlSessionFactory);
// return factory;
// }
//
// @Bean
// public MapperFactoryBean<Mapper2> mapper2(SqlSessionFactory sqlSessionFactory){
// MapperFactoryBean<Mapper2> factory = new MapperFactoryBean<>(Mapper2.class);
// factory.setSqlSessionFactory(sqlSessionFactory);
// return factory;
// }
}
- 也可以批量扫描某路径下所有接口
public class BeanScanPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
try {
CachingMetadataReaderFactory cachingMetadataReaderFactory = new CachingMetadataReaderFactory();
// 这里要注意内部类classpath的写法
MetadataReader metadataReader = cachingMetadataReaderFactory.getMetadataReader(new ClassPathResource("com/prac/springbootdemo/bean_factory_post_processor/BeanFactoryPostProcessorTests$Config.class"));
Set<MethodMetadata> annotatedMethods = metadataReader.getAnnotationMetadata().getAnnotatedMethods(Bean.class.getName());
for (MethodMetadata method : annotatedMethods) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition();
builder.setFactoryMethodOnBean(method.getMethodName(),"Config");
builder.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR); // 不加的话SqlSessionFactoryBean无法注入
String initMethod = method.getAnnotationAttributes(Bean.class.getName()).get("initMethod").toString();
System.out.println("获取到initMethod: "+ initMethod);
if (initMethod.length() > 0){
builder.setInitMethodName(initMethod);
}
AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
if (configurableListableBeanFactory instanceof DefaultListableBeanFactory){
DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) configurableListableBeanFactory;
beanFactory.registerBeanDefinition(method.getMethodName(),beanDefinition);
}
}
}catch (Exception e){
}
}
}
# 自己实现@Mapper扫描
/**
* 2022/6/4
* 这里实现BeanDefinitionRegistryPostProcessor 方法里就不用强转工厂来注册BeanDefinition
*/
public class MapperScanPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
}
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanFactory) throws BeansException {
try {
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
Resource[] resources = resolver.getResources("classpath:com/prac/springbootdemo/bean_factory_post_processor/mapper/**/*.class");
CachingMetadataReaderFactory cachingMetadataReaderFactory = new CachingMetadataReaderFactory();
AnnotationBeanNameGenerator generator = new AnnotationBeanNameGenerator();
for (Resource resource : resources) {
MetadataReader metadataReader = cachingMetadataReaderFactory.getMetadataReader(resource);
ClassMetadata classMetadata = metadataReader.getClassMetadata();
if (classMetadata.isInterface()){
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(MapperFactoryBean.class)
.addConstructorArgValue(classMetadata.getClassName())
.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE)
.getBeanDefinition();
// 这里获取beanName不能这样做 这样获取到的是MapperFactoryBean
// String beanName = generator.generateBeanName(beanDefinition, beanFactory);
// 应该重新获取mapper的bean定义信息
AbstractBeanDefinition mapperBeanDefinition = BeanDefinitionBuilder.genericBeanDefinition(metadataReader.getClassMetadata().getClassName()).getBeanDefinition();
String beanName = generator.generateBeanName(mapperBeanDefinition, beanFactory);
beanFactory.registerBeanDefinition(beanName,beanDefinition);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}