Spring源码——BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor

10 篇文章 0 订阅
7 篇文章 1 订阅

Spring5.0.2

准备

package cn.example;

public class Blue {
    public Blue() {
        System.out.println("Blue---Constructor");
    }
}
package cn.example.ext;

public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames();
        for (String beanDefinitionName : beanDefinitionNames) {
            System.out.println(beanDefinitionName);
        }
        System.out.println("一共声明了" + beanFactory.getBeanDefinitionCount() + "个组件"); 
        
        System.out.println("MyBeanFactoryPostProcessor---postProcessBeanFactory");
    }
}
package cn.example.ext;

@Configuration
public class ExtConfig {
    @Bean
    public MyBeanFactoryPostProcessor myBeanFactoryPostProcessor() {
        return new MyBeanFactoryPostProcessor();
    }

    @Bean
    public Blue blue() {
        return new Blue();
    }
}

package cn.example.ext;

public class Test01 {
    @Test
    public void test01() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(ExtConfig.class);
    }
}

执行结果:

org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
extConfig
myBeanFactoryPostProcessor
blue
一共声明了9个组件
MyBeanFactoryPostProcessor---postProcessBeanFactory
Blue---Constructor

源码-BeanFactoryPostProcessor

BeanFactoryPostProcessor接口的源码:

@FunctionalInterface
public interface BeanFactoryPostProcessor {

	/**
	 * Modify the application context's internal bean factory after its standard
	 * initialization. All bean definitions will have been loaded, but no beans
	 * will have been instantiated yet. This allows for overriding or adding
	 * properties even to eager-initializing beans.
	 * @param beanFactory the bean factory used by the application context
	 * @throws org.springframework.beans.BeansException in case of errors
	 */
	void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

}

注释的大致意思是:BeanFactoryPostProcessor 的作用是在标准初始化之后修改应用程序上下文的BeanFactory。调用时机————也就是在所有Bean定义已经加载到BeanFactory中,但是Bean的实例还未创建时调用它的方法

所以上面示例中,能在postProcessBeanFactory()中统计BeanFactory中所有Bean的个数并打印Bean的名称,而且是先打印了MyBeanFactoryPostProcessor---postProcessBeanFactory再打印了Blue---Constructor

小知识:PostProcessor原本意思就是后置处理器,所以BeanFactoryPostProcessor本意就是BeanFactory的后置处理器,能在BeanFactory创建过程中进行拦截去做些其他事情。

调试分析

postProcessBeanFactory()入口打上断点,查看方法调用链:
在这里插入图片描述
步骤1、IOC容器的创建
步骤2、invokeBeanFactoryPostProcessors(beanFactory);的执行
这个方法就是要将BeanFactory的后置处理器注册到容器中
在这里插入图片描述
部分源码:

try {
	// Allows post-processing of the bean factory in context subclasses.
	postProcessBeanFactory(beanFactory);
	
	// Invoke factory processors registered as beans in the context.
	// 这个地方。。。。。。。。。。。。。
	invokeBeanFactoryPostProcessors(beanFactory);
	
	// Register bean processors that intercept bean creation.
	registerBeanPostProcessors(beanFactory);
	
	// Initialize message source for this context.
	initMessageSource();
	
	// Initialize event multicaster for this context.
	initApplicationEventMulticaster();
	
	// Initialize other special beans in specific context subclasses.
	onRefresh();
	
	// Check for listener beans and register them.
	registerListeners();
	
	// Instantiate all remaining (non-lazy-init) singletons.
	// 这个地方才开始Bean的初始化。。。。。。。。。。。。。
	finishBeanFactoryInitialization(beanFactory);
	
	// Last step: publish corresponding event.
	finishRefresh();
	}

步骤2.1、注册过程
在这里插入图片描述
先执行实现了PriorityOrdered接口类的BeanFactoryPostProcessors,再执行实现了Ordered接口类的BeanFactoryPostProcessors,最后才执行其他类的BeanFactoryPostProcessors,我们自定义的MyBeanFactoryPostProcessors类就属于这种
步骤2.2 、注册过程
在下面这个for循环中,找去实现了BeanFactoryPostProcessors接口的Bean的名字,然后加入到nonOrderedPostProcessors集合中

class PostProcessorRegistrationDelegate {

	public static void invokeBeanFactoryPostProcessors(
		//................省略其他源码
		
		// Do not initialize FactoryBeans here: We need to leave all regular beans
		// uninitialized to let the bean factory post-processors apply to them!
		// 1. 通过类型BeanFactoryPostProcessor找Bean的名称,此时Bean是还没有
		//	  被初始化的,Bean初始化之前,要先去执行BeanFactoryPostProcessor的程序,
		//	  所以要先找到那些类实现了BeanFactoryPostProcessor接口
		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 {
			    //2. 把没有实现优先级接口但实现了
			    //   BeanFactoryPostProcessors接口的Bean的名称
			    //   加入到nonOrderedPostProcessorNames集合中
				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);
		
		//4. 根据nonOrderedPostProcessorNames集合中Bean的名称,
		//   到Bean工厂中获取对类的信息加入到
		//   nonOrderedPostProcessors集合中
		// Finally, invoke all other BeanFactoryPostProcessors.
		List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
		for (String postProcessorName : nonOrderedPostProcessorNames) {
			nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		// 这个方法就是下图调试到的地方
		// 5. 执行nonOrderedPostProcessors集合中Bean的postProcessBeanFactory
		invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

		// Clear cached merged bean definitions since the post-processors might have
		// modified the original metadata, e.g. replacing placeholders in values...
		beanFactory.clearMetadataCache();
	}
	//................省略其他源码
}

可以看到此时nonOrderedPostProcessors集合中就只记录了一个Bean,就是我们自定义的类
在这里插入图片描述

步骤3 、执行postProcessBeanFactory()方法
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
现在程序就执行到我们打断点的地方,这就是执行到这个地方时的函数调用链

BeanDefinitionRegistryPostProcessor

自定义MyBeanDefinitionRegistryPostProcessor:

public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
    /**
     * @param registry Bean定义信息的保存中心,
     *                 以后BeanFactory就是按照BeanDefinitionRegistry
     *                 里边保存的每一个bean的定义信息创建实例,
     *                 比如Bean的id、类型、多例的还是单例的
     *
     * @throws BeansException
     */
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        System.out.println("START-MyBeanDefinitionRegistryPostProcessor-postProcessBeanDefinitionRegistry");
        String[] beanDefinitionNames = registry.getBeanDefinitionNames();
        for (String beanDefinitionName : beanDefinitionNames) {
            System.out.println(beanDefinitionName);
        }
        System.out.println("Bean的数量" + registry.getBeanDefinitionCount());
        RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(Blue.class);
        registry.registerBeanDefinition("blue",rootBeanDefinition);
        System.out.println("END-MyBeanDefinitionRegistryPostProcessor-postProcessBeanDefinitionRegistry");
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("MyBeanDefinitionRegistryPostProcessor-postProcessBeanFactory");
        System.out.println("Bean的数量" + beanFactory.getBeanDefinitionCount());
    }
}
@ComponentScan("cn.example.ext")
@Configuration
public class ExtConfig {
//    @Bean
//    public MyBeanFactoryPostProcessor myBeanFactoryPostProcessor() {
//        return new MyBeanFactoryPostProcessor();
//    }

    @Bean
    public MyBeanDefinitionRegistryPostProcessor myBeanDefinitionRegistryPostProcessor() {
        return new MyBeanDefinitionRegistryPostProcessor();
    }
}

执行Test01.test01()方法:

START-MyBeanDefinitionRegistryPostProcessor-postProcessBeanDefinitionRegistry
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
extConfig
myBeanDefinitionRegistryPostProcessor
Bean的数量8
END-MyBeanDefinitionRegistryPostProcessor-postProcessBeanDefinitionRegistry
MyBeanDefinitionRegistryPostProcessor-postProcessBeanFactory
Bean的数量9
Blue---Constructor

BeanDefinitionRegistryPostProcessor是优先于BeanFactoryPostProcessor执行的,在BeanFactoryPostProcessor中说过,它是在所有Bean定义已经加载到BeanFactory中才开始执行的,那么,这个Bean定义信息就是保存在BeanDefinitionRegistry 中,在BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法中可以获取Bean的定义信息,还可以给容器中额外增加一些组件。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
BeanFactoryPostProcessorBeanDefinitionRegistryPostProcessorSpring 框架中用于对 BeanFactoryBeanDefinition 进行后置处理的接口。它们之间有一些区别和联系。 区别: 1. 触发时机不同:BeanFactoryPostProcessorBeanFactory 标准初始化之后,所有的 bean 定义已经加载到容器中,是还没有实例化 bean。而 BeanDefinitionRegistryPostProcessorBeanFactoryPostProcessor 之前触发,用于处理 bean 的定义信息。 2. 处理的对象不同:BeanFactoryPostProcessor 主要用于对已经加载的 BeanFactory 进行后置处理,例如修改 bean 的定义、添加新的 bean 定义等。而 BeanDefinitionRegistryPostProcessor 则是在 BeanFactoryPostProcessor 之前对 BeanDefinition 进行操作,可以注册新的 bean 定义、修改已有的 bean 定义等。 联系: 1. 都可以用于修改或扩展应用程序上下文中的 bean 定义,从而影响 bean 的创建和配置。 2. 都可以通过实现相应的接口来实现自定义的后置处理逻辑。 3. BeanDefinitionRegistryPostProcessor 继承自 BeanFactoryPostProcessor 接口,因此 BeanDefinitionRegistryPostProcessor 可以同时执行 BeanFactoryPostProcessor 的功能。 总结起来,BeanFactoryPostProcessorBeanDefinitionRegistryPostProcessor 都是用于对 bean 定义和 bean 工厂进行后置处理的接口,不同的是它们触发的时机和处理的对象不同。BeanDefinitionRegistryPostProcessorBeanFactoryPostProcessor 之前触发,用于处理 bean 的定义信息,而 BeanFactoryPostProcessorBeanFactory 标准初始化之后触发,用于处理已经加载的 BeanFactory

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值