Spring源码——BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor

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的定义信息,还可以给容器中额外增加一些组件。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值