Spring源码之BeanFactoryPostProccessor

1、容器的初始化

Spring容器的初始化通常认为两种方式,xml方式和注解方式。下面分别来进行介绍

xml方式

ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("mySpring.xml");

看下构造方法:

	public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
		this(new String[] {configLocation}, true, null);
	}

继续看:

	public ClassPathXmlApplicationContext(
			String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
			throws BeansException {
		// 设置父容器
		super(parent);
      	// 设置配置文件的文件
		setConfigLocations(configLocations);
      	 // refresh=true,会来执行刷新操作
		if (refresh) {
			refresh();
		}
	}

那么这里需要执行refresh方法

	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			StartupStep contextRefresh = this.applicationStartup.start("Spring.context.refresh");

			// Prepare this context for refreshing.
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
			
			// Prepare the bean factory for use in this context.
			prepareBeanFactory(beanFactory);

			try {
				// Allows post-processing of the bean factory in context subclasses.
				postProcessBeanFactory(beanFactory);

				StartupStep beanPostProcess = this.applicationStartup.start("Spring.context.beans.post-process");
				// Invoke factory processors registered as beans in the context.
				invokeBeanFactoryPostProcessors(beanFactory);
             ...................   
            }

在prepareBeanFactory方法上有一行注释:准备上下文beanfactory,那么上面也就是创建过程了。

所以是在上面进行创建的beanfactory。

注解方式

        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
        context.register(AppConfig.class);
        context.refresh();

在AnnotationConfigApplicationContext的无参构造方法中:

	public AnnotationConfigApplicationContext() {
        super();
		this.reader = new AnnotatedBeanDefinitionReader(this);
		this.scanner = new ClassPathBeanDefinitionScanner(this);
	}

首先来访问父类中的无参构造

private final DefaultListableBeanFactory beanFactory;

public GenericApplicationContext() {
	this.beanFactory = new DefaultListableBeanFactory();
}

那么获取得到对应的容器之后,接着看

this.reader = new AnnotatedBeanDefinitionReader(this);

将当前AnnotationConfigApplicationContext当做参数放入进去

	public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
		this(registry, getOrCreateEnvironment(registry));
	}

看下一个构造方法:

// Create a new AnnotatedBeanDefinitionReader for the given registry, using the given Environment.
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
		Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
		Assert.notNull(environment, "Environment must not be null");
		this.registry = registry;
		this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
		AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
	}


	public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
		registerAnnotationConfigProcessors(registry, null);
	}

利用工具类来向容器中注册处理器,那么直接看registerAnnotationConfigProcessors方法

	public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
			BeanDefinitionRegistry registry, @Nullable Object source) {
        
		DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
        
        // 初始化操作
		if (beanFactory != null) {
			if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
				beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
			}
			if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
				beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
			}
		}

		Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
		
        // 如果BeanDefinitionRegistry不包含这个BeanDefinition的名称,那么创建RootBeanDefinition
        // 注册到BeanDefinition
		if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
		if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
		if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition();
			try {
				def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
						AnnotationConfigUtils.class.getClassLoader()));
			}
			catch (ClassNotFoundException ex) {
				throw new IllegalStateException(
						"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
			}
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
		}

		if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
		}

		return beanDefs;
	}

那么也就是说这里是将Spring中内置的类解析成BeanDefinition,放入到BeanDefinitionMap中去,这个步骤在:

	private static BeanDefinitionHolder registerPostProcessor(
			BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {
		
		definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
		registry.registerBeanDefinition(beanName, definition);
        // 因为没有bean的名称,所以这里需要创建一个放入进去
		return new BeanDefinitionHolder(definition, beanName);
	}

那么放入的BeanDefinition看下是哪些:

// The bean name of the internally managed Configuration annotation processor.
org.Springframework.context.annotation.internalConfigurationAnnotationProcessor
								|
    				ConfigurationClassPostProcessor
    							|
    
// The bean name of the internally managed Autowired annotation processor.    
org.Springframework.context.annotation.internalAutowiredAnnotationProcessor
								|
    				AutowiredAnnotationBeanPostProcessor
    							|    
    
// The bean name of the internally managed JSR-250 annotation processor    
org.Springframework.context.annotation.internalCommonAnnotationProcessor
								|
    				CommonAnnotationBeanPostProcessor
    							|    
    
// The bean name of the internally managed JPA annotation processor.    
org.Springframework.context.event.internalEventListenerFactory    
								|
    				EventListenerMethodProcessor
    							|    
    
// The bean name of the internally managed @EventListener annotation processor.    
org.Springframework.context.event.internalEventListenerProcessor  
								|
    				DefaultEventListenerFactory
    							|    

只要是熟练使用过的,那么这里就应该非常清楚。这里对应的都是对应的后置处理器,也就是对应的BeanFactoryPostProccessor来操作的内容。

ConfigurationClassPostProcessor、AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor、EventListenerMethodProcessor、DefaultEventListenerFactory将这几个注册称为BeanDefinition

这五个BeanDefinition是Spring开天辟地时候放入的5个BeanDefinition。

那么我好奇的是这里默认的BeanDefinition是如何来进行处理的呢?

其实在上面的容器初始化代码中有意识的截取了一行代码:

// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);

调用BeanFactoryPostProcessor称为容器中的bean,那么这就代表着在上面定义的各种BeanFactoryPostProccessor对应的BeanDefinition要成为bean了么?

那么来思考一个问题:通常认为BeanDefinition要想称为一个bean,需要经历过完成的生命周期。但是这一步本来不是应该在扫描当前项目中所有包之后做的事情么?但是这里却提前了一大步!!但是这里还没有经过扫描,却在这里让一些BeanDefinition成为bean,那么对于这些BeanDefinition来说,可以理解Spring想要自己当前内置的一些BeanDefinition成为bean之后,让这些bean来做一些事情。至于是做了什么事情呢?下面将会来研究。

2、BeanFactoryPostProccessor

BeanFactoryPostProccessor是一个接口:

public interface BeanFactoryPostProcessor {
	
    /**
    * 在标准初始化之后修改应用程序上下文的内部 bean 工厂。 
    * 所有 bean 定义都将被加载,但还没有 bean 被实例化。
    * 这允许覆盖或添加属性,甚至是急切初始化的 bean。 
    * 参数:beanFactory - 应用程序上下文使用的 bean 
    * 工厂抛出:BeansException - 发生错误时
    */
	void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

}

那么直接看一下这个类的中文注释:

允许自定义修改应用程序上下文的 bean 定义,调整上下文底层 bean 工厂的 bean 属性值。
对于针对覆盖应用程序上下文中配置的 bean 属性的系统管理员的自定义配置文件很有用。有关满足此类配置需求的开箱即用解决方案,请参阅 PropertyResourceConfigurer 及其具体实现。
BeanFactoryPostProcessor 可以与 bean 定义交互和修改,但不能与 bean 实例交互。这样做可能会导致过早的 bean 实例化,违反容器并导致意外的副作用。如果需要 bean 实例交互,请考虑实现 BeanPostProcessor。
登记
ApplicationContext 在其 bean 定义中自动检测 BeanFactoryPostProcessor bean,并在创建任何其他 bean 之前应用它们。 BeanFactoryPostProcessor 也可以通过 ConfigurableApplicationContext 以编程方式注册。
订购
在 ApplicationContext 中自动检测到的 BeanFactoryPostProcessor bean 将根据 org.Springframework.core.PriorityOrdered 和 org.Springframework.core.Ordered 语义进行排序。相反,使用 ConfigurableApplicationContext 以编程方式注册的 BeanFactoryPostProcessor bean 将按注册顺序应用;对于以编程方式注册的后处理器,将忽略通过实现 PriorityOrdered 或 Ordered 接口表达的任何排序语义。此外,对于 BeanFactoryPostProcessor bean,不考虑 @Order 注释。

也就是说在上下文初始化完成之后,所有的BeanDefinition都已经被加载完了,但是BeanDefinition还没有完成实例化,那么可以在BeanFactoryPostProccessor的作用下来进行BeanDefinition中的属性修改等等信息。

BeanFactoryPostProccessor是beanfactory的后置处理器,可以用来干预beanfactory的产生的BeanDefinition,也就是我们可以对beanfactory来做操作

重点说明:

  • 所有 BeanDefinition都将被加载,但还没有 bean 被实例化
  • 在标准初始化之后修改应用程序上下文的内部 bean 工厂中的BeanDefinition;
  • 这允许覆盖或添加属性,甚至是急切初始化的 bean;但是Spring不推荐,因为可能会违背bean实例在容器中的完整生命周期处理方式;
  • 允许自定义修改应用程序上下文的 bean 定义,调整上下文底层 bean 工厂的 bean 属性值;
  • 用户可以自定义实现BeanFactoryPostProcessor,忽略PriorityOrdered 或 Ordered来进行排序;

BeanDefinitionRegistryPostProcessor

非常重要的一个类。直接看对类的说明

/**
* 对标准 BeanFactoryPostProcessor SPI 的扩展,允许在常规 BeanFactoryPostProcessor 
* 检测开始之前注册进一步的 bean 定义。特别是,BeanDefinitionRegistryPostProcessor 
* 可以注册进一步的 bean 定义,这些定义反过来定义 BeanFactoryPostProcessor 实例
 */
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {

	/**
	 * 在标准初始化之后修改应用程序上下文的内部 bean 定义注册表。 所有常规 bean 定义都将被加载,
	 * 但还没有实例化任何 bean。 这允许在下一个后处理阶段开始之前添加更多的 bean 定义。
     * 参数:registry - 应用程序上下文使用的 bean 定义注册表
	 */
	void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;

}

重点的地方在于:

  • 1、允许在常规 BeanFactoryPostProcessor检测开始之前注册进一步的 bean 定义;
  • 2、BeanDefinition反过来作用域BeanFactoryPostProcessor实例;

那么也就是说对于实现了BeanDefinitionRegistryPostProcessor接口的实现类来说,此时此刻已经具备了两种功能:

  • 1、postProcessBeanDefinitionRegistry可以提前注册BeanDefinition;
  • 2、BeanFactoryPostProccessor可以在上下文对象初始化后对BeanDefinition做操作;
  • 3、可以以自定义方式来添加BeanDefinition;

3、BeanDefinitionRegistryPostProcessor使用

那么这个类在哪里使用到的呢?在创建容器的时候就已经使用到了

        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        applicationContext.register(AppConfig.class);
        applicationContext.refresh();

看一下refresh中的invokeBeanFactoryPostProcessors(beanFactory)方法:

	protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
		..........
	}

看一下调用后置处理器方法,下面这行代码非常长,但是有大量的代码注释可以阅读。

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

		// WARNING: Although it may appear that the body of this method can be easily
		// refactored to avoid the use of multiple loops and multiple lists, the use
		// of multiple lists and multiple passes over the names of processors is
		// intentional. We must ensure that we honor the contracts for PriorityOrdered
		// and Ordered processors. Specifically, we must NOT cause processors to be
		// instantiated (via getBean() invocations) or registered in the ApplicationContext
		// in the wrong order.
		//
		// Before submitting a pull request (PR) to change this method, please review the
		// list of all declined PRs involving changes to PostProcessorRegistrationDelegate
		// to ensure that your proposal does not result in a breaking change:
		// https://github.com/Spring-projects/Spring-framework/issues?q=PostProcessorRegistrationDelegate+is%3Aclosed+label%3A%22status%3A+declined%22

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

		if (beanFactory instanceof BeanDefinitionRegistry) {
			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
			List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
			List<BeanDefinitionRegistryPostProcessor> 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<BeanDefinitionRegistryPostProcessor> 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, beanFactory.getApplicationStartup());
			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, beanFactory.getApplicationStartup());
			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, beanFactory.getApplicationStartup());
				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<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<>(orderedPostProcessorNames.size());
		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<>(nonOrderedPostProcessorNames.size());
		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();
	}

这个类利用后置处理器中的postProcessBeanDefinitionRegistry向容器中来注册一些bean。为什么是注册Bean?

因为前面有一些BeanDefinition已经生成(比如Spring开天辟地的五个BeanDefinition),在这里来进行创建,方便在下面来进行使用而已。

为了更好的分析,首先按照注释来将代码进行切分

Question一、Spring先调用程序员设置的BeanDefinitionRegistryPostProcessors

如果有程序员设置的BeanDefinitionRegistryPostProcessors,那么先来执行程序员设置的BeanDefinitionRegistryPostProcessors。

代码如下所示:

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

如果BeanDefinitionRegistry有BeanDefinitionRegistryPostProcessors的beandefinition,那么先调用。

但是这个集合在这里并没有来进行使用,而是在下面使用的。也就是说,可以理解成processedBeans存储的是BeanDefinitionRegistryPostProcessors对应的名称。

优先执行BeanDefinitionRegistryPostProcessors对应的代码:

			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
			
			// 存放的是所有的BeanFactoryPostProcessor的对象
			List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();

			// 存放的是所有的BeanDefinitionRegistryPostProcessor对象
			List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
			
			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
                // look here
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
					BeanDefinitionRegistryPostProcessor registryProcessor =
							(BeanDefinitionRegistryPostProcessor) postProcessor;
                    
					registryProcessor.postProcessBeanDefinitionRegistry(registry);
					registryProcessors.add(registryProcessor);
				}
				else {
					regularPostProcessors.add(postProcessor);
				}
			}

这里注意到一点:beanFactoryPostProcessors是从哪里来的?从参数部分进来的,那么看一下上一步如何传入进来的:

PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

直接调用getBeanFactoryPostProcessors()方法,那么看一下这个方法:

private final List<BeanFactoryPostProcessor> beanFactoryPostProcessors = new ArrayList<>();

public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
		return this.beanFactoryPostProcessors;
	}

那么这个时候问题又来了,在哪来往里面来set值呢?

首先看一下beanFactoryPostProcessors是在AbstractApplicationContext中的,而AnnotationConfigApplicationContext正好是其一个实现类,对应的方法是:

	public void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor) {
		Assert.notNull(postProcessor, "BeanFactoryPostProcessor must not be null");
		this.beanFactoryPostProcessors.add(postProcessor);
	}

那么做个Demo:

public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        
    }

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

    }
}

        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
        context.register(AppConfig.class);
        context.addBeanFactoryPostProcessor(new MyBeanDefinitionRegistryPostProcessor());
        context.refresh();

再次回到上面遍历的时候,这里的beanFactoryPostProcessors就会有值了。(正常的时候这里是没有值的

			List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
			// 存放的是所有的BeanDefinitionRegistryPostProcessor对象
			List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
			
			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
                // look here
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
					BeanDefinitionRegistryPostProcessor registryProcessor =
							(BeanDefinitionRegistryPostProcessor) postProcessor;
                   
					registryProcessor.postProcessBeanDefinitionRegistry(registry);
					registryProcessors.add(registryProcessor);
				}
				else {
					regularPostProcessors.add(postProcessor);
				}

我写了一个MyBeanDefinitionRegistryPostProcessor,这里就会直接执行postProcessBeanDefinitionRegistry方法,然后将

MyBeanDefinitionRegistryPostProcessor对象直接放入到regularPostProcessors中来

所以说在registryProcessors中的都是BeanDefinitionRegistryPostProcessor的对象

但是还有一个判断,如果不是BeanDefinitionRegistryPostProcessor,却又是BeanFactoryPostProcessor,那么就只能是BeanFactoryPostProcessor的子类了,说明regularPostProcessors里面放入的只能够是BeanFactoryPostProcessor

问题:但是真的有人会来实现BeanDefinitionRegistryPostProcessor这个接口来做实现么?

一般情况下,都是利用BeanFactoryPostProcessor来进行实现,添加后置处理器而已。但是在开源框架mybatis中使用了这个类。后续会讲解。

然后看下面的代码的注释

// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.

也就是说,对BeanDefinitionRegistryPostProcessors来进行划分责任

  • 1、BeanDefinitionRegistryPostProcessors+实现了PriorityOrdered的BeanDefinitionRegistryPostProcessors;
  • 2、BeanDefinitionRegistryPostProcessors+Ordered接口的BeanDefinitionRegistryPostProcessors;
  • 3、其他的BeanDefinitionRegistryPostProcessors,也就是说没有实现BeanDefinitionRegistryPostProcessors的子类;

那么这里就可以来理解:

// 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<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

也就是说这里盛放的是BeanDefinitionRegistryPostProcessor实现了PriorityOrdered, Ordered和没有实现的BeanDefinitionRegistryPostProcessor。

但是又可以看到一个非常奇怪的现象:

			List<BeanDefinitionRegistryPostProcessor> 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, beanFactory.getApplicationStartup());

			currentRegistryProcessors.clear();

找到BeanDefinitionRegistryPostProcessor之后,遍历添加之后,又对其做清除处理,那么这样就表示针对PriorityOrdered、Ordered以及不加的情况下就已经处理结束了,下面的都是类似的思想。

需要注意的是:

  • 1、所有处理过的BeanDefinitionRegistryPostProcessor对应的名称都将会存入到processedBeans这个结合中来,表示将处理过的BeanDefinitionRegistryPostProcessor实现出来。
  • 2、所有的BeanDefinitionRegistryPostProcessor不管是是PriorityOrdered、Ordered以及不加的使用完成之后,都会将其当前正在处理的BeanDefinitionRegistryPostProcessor的对象放入到registryProcessors中来,表示哪些BeanDefinitionRegistryPostProcessor是从容器中获取得到出来的bean且BeanDefinition还是Spring内置的;因为这个时候只有Spring内置的才产生了BeanDefinition,其他的没有。当前也有可能是使用这自己放进去的。而在Spring内置的BeanDefinitionRegistryPostProcessor中,只有一个ConfigurationClassPostProcessor类实现了BeanDefinitionRegistryPostProcessor这个接口以及PriorityOrdered接口,ConfigurationClassPostProcessor也没有实现PriorityOrdered接口,所以说在registryProcessors中的只有BeanDefinitionRegistryPostProcessor的子类,就原生的Spring来说,也就只有一个。目前来说,只有ConfigurationClassPostProcessor。目前暂时不考虑我创建的MyBeanDefinitionRegistryPostProcessor这个类。

Question二、Spring将BeanDefinitionRegistryPostProcessor扫描出来的放在了registryProcessors是干嘛的

因为BeanDefinitionRegistryPostProcessor是实现了BeanFactoryPostProcessor接口的,我们在代码中可以看到,每处理完一个BeanDefinitionRegistryPostProcessor就会来执行对应的postProcessBeanDefinitionRegistry方法,但是对于父类中BeanFactoryPostProcessor中的postProcessBeanFactory还没有来执行!!!!

那么是否需要利用BeanDefinitionRegistryPostProcessor来执行父类BeanFactoryPostProcessor中的postProcessBeanFactory的方法呢?

Spring中也来使用,如下代码:

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

第一行是BeanDefinitionRegistryPostProcessor对象执行postProcessBeanFactory方法;

第二行是BeanFactoryPostProcessor执行postProcessBeanFactory方法

下面接着看一个代码,也就是while(true)的代码

			// 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, beanFactory.getApplicationStartup());
				currentRegistryProcessors.clear();
			}

也就是说既不是实现了PriorityOrdered接口和Ordered接口的BeanDefinitionRegistryPostProcessor对象

只有执行到reiterate = true;的代码的时候,才会去判断下一个是否还有,如果还有,就继续遍历而已。

也就是说获取得到所有的既不是实现了PriorityOrdered接口和Ordered接口的BeanDefinitionRegistryPostProcessor对象而已

但是!但是!但是!

如果此时此刻,万一又有一个新的BeanDefinitionRegistryPostProcessor对应的BeanDefinition产生呢

首先来思考为什么会产生一个?那么有没有可能是在postProcessBeanDefinitionRegistry方法中利用BeanDefinitionRegistry来产生一个新的BeanDefinition:

public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {

	void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
	
}

答案是可能的,所以这里做了while循环判断操作。

但是我思考了一下,如果要是真的有这种操作的话,那么对于第一次BeanDefinitionRegistryPostProcessor优先来执行postProcessBeanDefinitionRegistry的时候不是已经产生了么?后续就不应该再产生了新的BeanDefinitionRegistryPostProcessor对应的BeanDefinition了。

所以我怀疑这里的代码可能会有冗余了!

紧接着来看下一行代码:

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

这里开始来对BeanFactoryPostProcessor实现了PriorityOrdered、Ordered以及没有实现了的来作为一个添加。

这个时候可以比较上面的区别:没有bean的容器来创建了,只有BeanDefinition。

然后依次调用beanFactory.getBean来调用对应的postProcessBeanFactory方法了。

		// 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<>(orderedPostProcessorNames.size());
		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<>(nonOrderedPostProcessorNames.size());
		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();

那么这就意味着,我们也可以在容器创建的时候,将某些个BeanFactoryPostProcessor进行设置,让其也称为beandefinition,然后让其在这里产生作用;或者是Spring内置的BeanFactoryPostProcessor对应的beandefinition在此刻来产生作用。

Question三:processedBeans集合的作用

两个作用:

1、首先使用来记录BeanDefinitionRegistryPostProcessor对象的名称;

2、用来做判断;

为什么这么来说呢?因为除了第一个BeanDefinitionRegistryPostProcessor是实现了PriorityOrdered之外,在判断Ordered接口以及没有PriorityOrdered和Ordered的时候,这里都是做了是否包含的操作。也就是说只要不包含PriorityOrdered和Ordered接口的BeanDefinitionRegistryPostProcessor

Question四:两行代码的真正含义

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

首先分析一下这两个集合到底是保存什么的?

  • registryProcessors:保存程序员放进去的BeanDefinitionRegistryPostProcessor;
  • regularPostProcessors:不是程序员设置的BeanFactoryPostProcessor以及Spring内置的BeanFactoryPostProcessor;

这里也就是说,执行程序员放进去的BeanDefinitionRegistryPostProcessor中的实现了BeanFactoryPostProcessor方法以及Spring内置或者是程序员添加的BeanFactoryPostProcessor中的方法

首先确定最原始的beanFactoryPostProcessors是从外部而来的,是开发者自己来进行设置的。

1、如果开发者实现的是BeanDefinitionRegistryPostProcessor接口,说明实现了BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor中的两个方法。

那么会第一行代码中执行;但是如果没有提供呢?那么第二行代码就根本不会执行;那么此时只有内置的才会执行

2、如果开发者实现的是BeanFactoryPostProcessor接口,那么只会添加到regularPostProcessors集合中来,而第一行代码中只有内置才会自行。

BeanDefinitionRegistryPostProcessor的执行顺序

1、Spring会首先来执行程序员通过容器设置的BeanDefinitionRegistryPostProcessor(也就是这个invokeBeanFactoryPostProcessors方法第一个for循环的案例)

2、Spring才会来执行内置的BeanDefinitionRegistryPostProcessor或者是程序员实现的BeanDefinitionRegistryPostProcessor(实现PriorityOrdered或者Ordered接口的)

3、Spring来执行程序员实现的BeanDefinitionRegistryPostProcessor(没有任何特点的)

BeanFactoryPostProcessor的执行顺序

1、首先会来执行BeanDefinitionRegistryPostProcessor中的实现了BeanFactoryPostProcessor的方法;

2、普通BeanFactoryPostProcessor中的方法;也有分别:实现PriorityOrdered或者Ordered接口的和普通的

总结

想要在这个方法中来进行操作的前提:

要想让BeanDefinitionRegistryPostProcessor或者是BeanFactoryPostProcessor在这里生效,首先必须让其先成为一个BeanDefinition,也就是说需要向BeanDefinitionMap中来put一个我们自己的BeanDefinition即可。

在Spring中总结了三种能够产生BeanDefinition并且放入到BeanDefinitionMap中

1、通过容器来添加一个我们自己的BeanFactoryPostProcessor或者是BeanDefinitionRegistryPostProcessor会来执行;

2、Spring内置的一些BeanFactoryPostProcessor或者是BeanDefinitionRegistryPostProcessor;

3、我们能够手动产生一个BeanFactoryPostProcessor或者是BeanDefinitionRegistryPostProcessor的实现类,然后将其注册成BeanDefinition,在这个阶段也来执行????

invokeBeanFactoryPostProcessors(beanFactory);这个方法主要做了两件执行:

  • 先执行BeanDefinitionRegistryPostProcessor中的postProcessBeanDefinitionRegistry方法;
  • 再执行BeanFactoryPostProcessor中的postProcessBeanFactory方法;

所以对于BeanDefinitionRegistryPostProcessor的子类来说,会执行两次,第一次是postProcessBeanDefinitionRegistry,第二次是postProcessBeanFactory方法;对于BeanFactoryPostProcessor来说,只会执行一次postProcessBeanFactory对象。

我也在想一个问题:如果我也想在这个阶段来做一些事情,实现BeanDefinitionRegistryPostProcessor或者是BeanFactoryPostProcessor,然后将该类对应的BeadDefinition注册进去,在这里来进行操作。那么有没有什么方式呢?

哪些框架来进行整合的时候是这样子来操作的呢?新版本的Spring-mybatis整合中使用到。

4、解决上面的一个问题

我在3章节的总结过程中,提出来了一个问题:

我们能够手动产生一个BeanFactoryPostProcessor或者是BeanDefinitionRegistryPostProcessor的实现类,然后将其注册成BeanDefinition,在这个阶段也来执行????

这个已经有一个类做到了,是ConfigurationClassPostProcessor来做到了,那么直接看一下后置处理方法:

	public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
		int registryId = System.identityHashCode(registry);
		if (this.registriesPostProcessed.contains(registryId)) {
			throw new IllegalStateException(
					"postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
		}
		if (this.factoriesPostProcessed.contains(registryId)) {
			throw new IllegalStateException(
					"postProcessBeanFactory already called on this post-processor against " + registry);
		}
		this.registriesPostProcessed.add(registryId);

		processConfigBeanDefinitions(registry);
	}

直接看最后一行代码

5、扫描流程

下面做个研究:Spring和mybatis整合的时候,扫描@Mapper,那么搞懂这个之前,首先得搞懂Spring是如何扫描@Component的。

扫描器是在创建AnnotationConfigApplicationContext的时候已经创建好了

	public AnnotationConfigApplicationContext() {
		this.reader = new AnnotatedBeanDefinitionReader(this);
		this.scanner = new ClassPathBeanDefinitionScanner(this);
	}

首先来看一下ClassPathBeanDefinitionScanner的扫描流程(doScan方法中)

那么首先来看一行关键代码:

Set<BeanDefinition> candidates = findCandidateComponents(basePackage);

继续跟:

scanCandidateComponents(basePackage)

继续看:

private Set<BeanDefinition> scanCandidateComponents(String basePackage) {
		Set<BeanDefinition> candidates = new LinkedHashSet<>();
		try {
			String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
					resolveBasePackage(basePackage) + '/' + this.resourcePattern;
			Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);
			for (Resource resource : resources) {
				if (resource.isReadable()) {
					try {
						MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
						if (isCandidateComponent(metadataReader)) {
							ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
							sbd.setSource(resource);
							if (isCandidateComponent(sbd)) {
								if (debugEnabled) {
									logger.debug("Identified candidate component class: " + resource);
								}
								candidates.add(sbd);
							}
							............

通过IO操作,获取得到源文件,然后读取得到元信息,首先看一下isCandidateComponent(metadataReader)的实现:

	protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {
        // 是否需要根据规则排除
		for (TypeFilter tf : this.excludeFilters) {
			if (tf.match(metadataReader, getMetadataReaderFactory())) {
				return false;
			}
		}
        // 是否需要将其添加
        // Spring中有默认的实现:@Component和另外一个
		for (TypeFilter tf : this.includeFilters) {
			if (tf.match(metadataReader, getMetadataReaderFactory())) {
				return isConditionMatch(metadataReader);
			}
		}
		return false;
	}

上面的默认:如果类上是有@Component注解的,将会进入到创建BeanDefinition,然后对BeanDefinition来进行判断

isCandidateComponent(sbd)
	protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
		AnnotationMetadata metadata = beanDefinition.getMetadata();
		return (metadata.isIndependent() && (metadata.isConcrete() ||
				(metadata.isAbstract() && metadata.hasAnnotatedMethods(Lookup.class.getName()))));
	}

拿到描述类的元数据信息,判断是否是独立的类(顶级类和静态内部类)

类为是否为抽象类或者是接口或者是抽象的BeanDefinition以及方法上加了Lookup注解

如果上面的两个条件成立的话,那么将会称为一个BeanDefinition。

Spring做了两个事情:

1、类是否符合(非抽象非接口顶级类等);

2、将符合的注册称为BeanDefition;

所以在我们实现mybatis的@Mapper的时候,要注意三个事情:

  • 0、自定义一个扫描器来进行扫描;

  • 1、在类型匹配阶段,首先得保证为TRUE,这样子才会生成一个BeanDefinition;

  • 2、必须要来修改isCandidateComponent方法,保证mybatis中接口也能够添加到BeanDefinition中去

那么来整理一下思路,不需要自己来重新定义扫描规则,只需要只用Spring提供好了的扫描器来进行设计即可,所以我们继承一下ClassPathBeanDefinitionScanner即可

@Configuration
@ComponentScan("com.guang.beandefinitaiontest.demo6")
public class AppConfig {

}


@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Mapper {
}

@Mapper
public interface UserMapper {

}

下面来看我定义Scanner的思路即可:

public class MyScanner extends ClassPathBeanDefinitionScanner {

    public MyScanner(BeanDefinitionRegistry registry) {
        super(registry);
    }

    /**
     *
     * 自定义添加规则
     *
     * 但是debug源码的时候,发现在初始化的时候已经赋值了,这里么有来提供添加的API,所以采用另外的方式来操作
     * @param includeFilter
     */
//    @Override
//    public void addIncludeFilter(TypeFilter includeFilter) {
//        /**
//         * metadataReader: 读取到当前正在扫描的类的信息
//         * metadataReaderFactory : 可以获取到其他任何类的信息
//         */
//        super.addIncludeFilter((metadataReader, metadataReaderFactory)->{
//            ClassMetadata classMetadata = metadataReader.getClassMetadata();
//            AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
//            // 接口+@Mapper+独立类
//            return classMetadata.isInterface() && classMetadata.isIndependent() && annotationMetadata.hasAnnotation(Mapper.class.getName()) ;
//        });
//    }



    /**
     * 添加匹配规则
     * @param beanDefinition
     * @return
     */
    @Override
    protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
        AnnotationMetadata metadata = beanDefinition.getMetadata();
        return metadata.isInterface() && metadata.isIndependent();
    }
}

对应的测试类:

public class Test {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        applicationContext.register(AppConfig.class);
        // 放入到上面,不能够放在下面!因为如果放在下面了,生成的BeanDefinition需要生成bean,但是下面的无法生成
        applicationContext.refresh();
        MyScanner myScanner = new MyScanner(applicationContext);
        myScanner.addIncludeFilter(new AnnotationTypeFilter(Mapper.class));
        // 返回扫描了多少个
        int scanMapperCount = myScanner.scan("com.guang.beandefinitaiontest.demo6.service");
        System.out.println("扫描结果,返回扫描多少个:"+scanMapperCount);
        BeanDefinition userMapper = applicationContext.getBeanFactory().getBeanDefinition("userMapper");
        System.out.println(userMapper.getClass().getSimpleName());
    }
}

控制台显示:

扫描结果,返回扫描多少个:1
ScannedGenericBeanDefinition

还是来说明一个重要的类ConfigurationClassPostProcessor,当执行完成postProcessBeanDefinitionRegistry方法之后,紧接着就会来执行postProcessBeanFactory。那么看下这个里面做了什么事情。

			// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
			invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
private static void invokeBeanFactoryPostProcessors(
      Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {

   for (BeanFactoryPostProcessor postProcessor : postProcessors) {
	  // 开始来执行父类中的postProcessBeanFactory方法
      postProcessor.postProcessBeanFactory(beanFactory);
      postProcessBeanFactory.end();
   }
}

那么来看一下:

	/**
	 * Prepare the Configuration classes for servicing bean requests at runtime
	 * by replacing them with CGLIB-enhanced subclasses.
	 */
	// 通过将配置类替换为 CGLIB 增强的子类来准备配置类以在运行时为 bean 请求提供服务
	// 这里来开始处理@Configuration的类
	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		int factoryId = System.identityHashCode(beanFactory);
		if (this.factoriesPostProcessed.contains(factoryId)) {
			throw new IllegalStateException(
					"postProcessBeanFactory already called on this post-processor against " + beanFactory);
		}
		this.factoriesPostProcessed.add(factoryId);
		if (!this.registriesPostProcessed.contains(factoryId)) {
			// BeanDefinitionRegistryPostProcessor hook apparently not supported...
			// Simply call processConfigurationClasses lazily at this point then.
			processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
		}
		// 直接来看这个方法
		enhanceConfigurationClasses(beanFactory);
		beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
	}

下面来看这个方法:

	/**
	 * Post-processes a BeanFactory in search of Configuration class BeanDefinitions;
	 * any candidates are then enhanced by a {@link ConfigurationClassEnhancer}.
	 * Candidate status is determined by BeanDefinition attribute metadata.
	 * @see ConfigurationClassEnhancer
	 */
	public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) {
		
		Map<String, AbstractBeanDefinition> configBeanDefs = new LinkedHashMap<>();
		for (String beanName : beanFactory.getBeanDefinitionNames()) {
            
        }

在beanfactory中不止可以保存BeanDefinitionMap,还有一个String[]来保存所有BeanDefinition的名称。

posted @ 2022-08-16 15:46  写的代码很烂  阅读(5)  评论(0编辑  收藏  举报