(一)Spring 扩展点之 BeanFactoryPostProcessor

176 阅读2分钟

1、Spring 扩展点之 BeanFactoryPostProcessor

1.1、BeanDefinitionRegistryPostProcessor

该类实际上是继承了 BeanFactoryPostProcessor 的,并且在原有的方法上添加了一个 postProcessBeanDefinitionRegistry 方法。

void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;

该方法是在所有常规 Bean 定义信息被加载但是还未被实例化的时候调用。

作用:添加、修改 Bean 的定义信息。

源码调用处:PostProcessorRegistrationDelegate 的 invokeBeanFactoryPostProcessors 方法,这里的 BeanFactoryPostProcessor 是在初始化类一些类的时候添加到 beanFactoryPostProcessors 的。

for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
					BeanDefinitionRegistryPostProcessor registryProcessor =
							(BeanDefinitionRegistryPostProcessor) postProcessor;
// 这里调用
					registryProcessor.postProcessBeanDefinitionRegistry(registry);
					registryProcessors.add(registryProcessor);
				}
				else {
					regularPostProcessors.add(postProcessor);
				}
			}

我们来看下 Spring 默认加载的一些子类:

CachingMetadataReaderFactoryPostProcessor

SharedMetadataReaderFactoryContextInitializer 的内部类。

public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
}

public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
   this.register(registry);
   this.configureConfigurationClassPostProcessor(registry);
}

private void register(BeanDefinitionRegistry registry) {
            BeanDefinition definition = BeanDefinitionBuilder.genericBeanDefinition(SharedMetadataReaderFactoryContextInitializer.SharedMetadataReaderFactoryBean.class, SharedMetadataReaderFactoryContextInitializer.SharedMetadataReaderFactoryBean::new).getBeanDefinition();
            registry.registerBeanDefinition("org.springframework.boot.autoconfigure.internalCachingMetadataReaderFactory", definition);
        }

        private void configureConfigurationClassPostProcessor(BeanDefinitionRegistry registry) {
            try {
                BeanDefinition definition = registry.getBeanDefinition("org.springframework.context.annotation.internalConfigurationAnnotationProcessor");
                definition.getPropertyValues().add("metadataReaderFactory", new RuntimeBeanReference("org.springframework.boot.autoconfigure.internalCachingMetadataReaderFactory"));
            } catch (NoSuchBeanDefinitionException var3) {
            }

        }

我们发现它的作用就是添加了一个 org.springframework.boot.autoconfigure.internalCachingMetadataReaderFactory 的 Bean 定义信息,然后就是添加了个 PropertyValue -> metadataReaderFactory

ConfigurationWarningsPostProcessor

ConfigurationWarningsApplicationContextInitializer 的内部类。

@Override
		public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		}

		@Override
		public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
			for (Check check : this.checks) {
				String message = check.getWarning(registry);
				if (StringUtils.hasLength(message)) {
					warn(message);
				}
			}

		}

		private void warn(String message) {
			if (logger.isWarnEnabled()) {
				logger.warn(String.format("%n%n** WARNING ** : %s%n%n", message));
			}
		}

点进去发现(现在只有一个 Check 对象)它的作用是拿到所有的 ComponentScan 注解属性,然后检测它是否是 org.springframework 或者 org ,如果是则会打印异常信息 Your ApplicationContext is unlikely to start due to a @ComponentScan of

代码往下走,下面有三处调用 BeanDefinitionRegistryPostProcessor 类的,调用规则是先调用实现了PriorityOrdered接口的类,然后再调用Ordered的接口的类,最后就是剩余的BeanDefinitionRegistryPostProcessor类了。如果同时实现了 PriorityOrdered 与 Ordered,那么被调用过一次就不会再调用。

通过这个方法去遍历调用 postProcessBeanDefinitionRegistry。这里调用的 BeanDefinitionRegistryPostProcessor 是在 beanFactory 中拿的所有的与之匹配的类型,与上面的不一样。

invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);

1.2、BeanFactoryPostProcessor

void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

该方法调用时也是 Bean 定义信息已加载,并且还没有 Bean 被实例化。但是官方注解说是可以在这里先实例化 Bean 的。

This allows for overriding or adding properties even to eager-initializing beans.

接着上面的代理继续往下走,invokeBeanFactoryPostProcessors 是调用 postProcessBeanFactory 方法回调的,这里调用的是上面 BeanDefinitionRegistryPostProcessor 类型的 postProcessBeanFactory 方法,因为 BeanDefinitionRegistryPostProcessor 是继承了 BeanFactoryPostProcessor 的接口的,并且也没有默认实现父接口的方法,所以在实现 BeanDefinitionRegistryPostProcessor 接口的时候也要实现 postProcessBeanFactory 方法。

继续往下走,和 BeanDefinitionRegistryPostProcessor 类是一样的,它从 beanFactory 中拿所有 BeanFactoryPostProcessor 类型的 Bean,然后根据实现 PriorityOrdered 、Ordered 顺序调用,使用 invokeBeanFactoryPostProcessors 方法去遍历调用 postProcessBeanFactory 方法。

来看下 Spring 默认加载的一些 BeanFactoryPostProcessor。

EventListenerMethodProcessor

public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		this.beanFactory = beanFactory;

		Map<String, EventListenerFactory> beans = beanFactory.getBeansOfType(EventListenerFactory.class, false, false);
		List<EventListenerFactory> factories = new ArrayList<>(beans.values());
		AnnotationAwareOrderComparator.sort(factories);
		this.eventListenerFactories = factories;
	}

里面就初始化了自己的 eventListenerFactories 属性。

以上总结: Spring 的 BeanDefinitionRegistryPostProcessor 与 BeanFactoryPostProcessor 的实现类方法的调用顺序是->先调用 BeanDefinitionRegistryPostProcessor 的 postProcessBeanDefinitionRegistry 方法,顺序是 PriorityOrdered > Ordered > 其他。内部根据 order 值来判断顺序。再调用 BeanDefinitionRegistryPostProcessor 的 postProcessBeanFactory 方法,顺序判断也是一样。最后执行 BeanFactoryPostProcessor 的 postProcessBeanFactory 方法。