Spring IOC源码解析--invokeBeanFactoryPostProcessors控制后置处理器的bean加载顺序

spring设计的精髓,开方式接口。定义了很多空的逻辑,需要我们自己实现。

在org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors方法中,扫描bean定义的优先级。具体的顺序如下:

invokeBeanFactoryPostProcessorsy优先级


==>找出所有实现BeanDefinitionRegistryPostProcessor的实例
-->优先加载实现了PriorityOrdered的BeanDefinitionRegistryPostProcessor 
-->然后加载实现了Ordered的BeanDefinitionRegistryPostProcessor
-->然后加载没有任何实现的BeanDefinitionRegistryPostProcessor
==>找出所有实现BeanFactoryPostProcessor的实例
-->优先加载实现了PriorityOrdered的BeanFactoryPostProcessor
-->然后加载实现了Ordered的BeanFactoryPostProcessor
-->然后加载没有任何实现的BeanFactoryPostProcessor

 

这样设计的目的,分优先级创建,优先级高的可以对优先级低的进行拦截。

在我们具体的使用中,可以根据我们继承实现不同的类来控制对我们自定义的类的加载顺序:例子

实现BeanDefinitionRegistryPostProcessor 

package com.tuling.testbfpostprocessor;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.stereotype.Component;

/**
 * Created by smlz on 2019/5/26.
 */
@Component
public class TulingBeanDefinationRegisterPostProcessor implements BeanDefinitionRegistryPostProcessor {
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        System.out.println("TulingBeanDefinationRegisterPostProcessor的postProcessBeanDefinitionRegistry方法");
        System.out.println("bean定义的数据量:"+registry.getBeanDefinitionCount());
        RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(TulingLog.class);
        registry.registerBeanDefinition("tulingLog",rootBeanDefinition);
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("TulingBeanDefinationRegisterPostProcessor的postProcessBeanFactory方法");
        System.out.println(beanFactory.getBeanDefinitionCount());
    }
}

实现BeanFactoryPostProcessor 

package com.tuling.testbeanfacotoryPostProcessor;

import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;

/**
 *
 * Created by smlz on 2019/5/26.
 */
@Component
public class TulingBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("IOC 容器调用了TulingBeanFactoryPostProcessor的postProcessBeanFactory方法");
        for(String name:beanFactory.getBeanDefinitionNames()) {
            if("tulingLog".equals(name)) {
                BeanDefinition beanDefinition = beanFactory.getBeanDefinition(name);
                beanDefinition.setLazyInit(true);
            }

        }
    }
}

具体源码代码如下:

public static void invokeBeanFactoryPostProcessors(
	ConfigurableListableBeanFactory beanFactory, List beanFactoryPostProcessors) {

// Invoke BeanDefinitionRegistryPostProcessors first, if any.
Set processedBeans = new HashSet<>();

if (beanFactory instanceof BeanDefinitionRegistry) {
	BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
	List regularPostProcessors = new ArrayList<>();
	List registryProcessors = new ArrayList<>();

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

	// Do not initialize FactoryBeans here: We need to leave all regular beans
	// uninitialized to let the bean factory post-processors apply to them!
	// Separate between BeanDefinitionRegistryPostProcessors that implement
	// PriorityOrdered, Ordered, and the rest.
	List currentRegistryProcessors = new ArrayList<>();

	// 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();

	// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
	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();

	// 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();
	}

	// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
	invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
	invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}

else {
	// Invoke factory processors registered with the context instance.
	invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}

// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
String[] postProcessorNames =
		beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List priorityOrderedPostProcessors = new ArrayList<>();
List orderedPostProcessorNames = new ArrayList<>();
List 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 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 nonOrderedPostProcessors = new ArrayList<>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
	nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
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();
}

 

你可能感兴趣的:(spring,ioc,后置处理器bean加载顺序)