首页 > 其他分享 >Spring5 IOC容器解析——注解配置的资源定位、加载、解析、注册分析

Spring5 IOC容器解析——注解配置的资源定位、加载、解析、注册分析

时间:2023-01-07 18:32:39浏览次数:63  
标签:configClass beanFactory bean registry new 解析 IOC class Spring5

AnnotationConfigApplicationContext

使用AnnotationConfigApplicationContext可以实现基于Java的配置类(包括各种注解)加载Spring的应用上下文。避免使用application.xml进行配置。相比XML配置,更加便捷。

一、被@Configuration标记的Bean的资源定位、加载、解析、注册分析

ApplicationContext applicationContext = new AnnotationConfigApplicationContext(Xxx.class);
public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {

	//保存一个读取注解的Bean 定义读取器,并将其设置到容器中
	private final AnnotatedBeanDefinitionReader reader;
	//保存一个扫描指定类路径中注解Bean 定义的扫描器,并将其设置到容器中
	private final ClassPathBeanDefinitionScanner scanner;
	
	/**
	 * 默认构造函数,初始化一个空容器,容器不包含任何Bean 信息,需要在稍后通过调用其register()
	 * 方法注册配置类,并调用refresh()方法刷新容器,触发容器对注解Bean 的载入、解析和注册过程
	 * Create a new AnnotationConfigApplicationContext that needs to be populated
	 * through {@link #register} calls and then manually {@linkplain #refresh refreshed}.
	 */
	public AnnotationConfigApplicationContext() {
		this.reader = new AnnotatedBeanDefinitionReader(this);
		this.scanner = new ClassPathBeanDefinitionScanner(this);
	}	
	
	public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
		//调用默认无参构造器,主要初始化AnnotatedBeanDefinitionReader
		// 以及路径扫描器ClassPathBeanDefinitionScanner
		this();
		//把传入的Class进行注册,Class既可以有@Configuration注解,也可以没有@Configuration注解
		//如何注册委托给了 org.springframework.context.annotation.AnnotatedBeanDefinitionReader.register 方法进行注册
		// 包装传入的Class 生成 BeanDefinition , 注册到BeanDefinitionRegistry
		register(componentClasses);
		refresh();
	}

	@Override
	public void register(Class<?>... componentClasses) {
		Assert.notEmpty(componentClasses, "At least one component class must be specified");
		this.reader.register(componentClasses);
	}
}

AnnotatedBeanDefinitionReader

发现 AnnotatedBeanDefinitionReader没有继承和实现任何类与接口,即该类并不属于BeanDefinitionReader的体系,而是专门用于处理注解相关的BeanDefinition的配置读入,这样做可以用于区分出注解和其他配置方式的不同。

 

注解的处理逻辑相对更清晰,在上一文分析了XML相关的解析逻辑之后,理解注解也会相对容易一些。

深入this.reader.register(componentClasses)方法,进入AnnotatedBeanDefinitionReader类

public class AnnotatedBeanDefinitionReader {

	//还是委托BeanDefinitionRegistry将AnnotatedBeanDefinition实例注入到IOC容器中
	private final BeanDefinitionRegistry registry;

	public void register(Class<?>... componentClasses) {
		for (Class<?> componentClass : componentClasses) {
			registerBean(componentClass);
		}
	}

	public void registerBean(Class<?> beanClass) {
		doRegisterBean(beanClass, null, null, null, null);
	}
}

doRegisterBean()方法真正的注册方法,继续深入

public class AnnotatedBeanDefinitionReader {

	private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
			@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
			@Nullable BeanDefinitionCustomizer[] customizers) {

		AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
		//此段代码用于处理 Conditional 注解,在特定条件下阻断 bean 的注册
		if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
			return;
		}
		//用来创建 bean 的 supplier,会替代掉 bean 本身的创建方法
		//instanceSupplier 一般情况下为 null
		abd.setInstanceSupplier(supplier);
		//此行代码处理 scope 注解,本例中 scope 是默认值 singleton
		ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
		abd.setScope(scopeMetadata.getScopeName());
		//获取beanName
		String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));

		//特定注解解析,本例中均没传入dependsOn,LazyInit这些注解
		//这些注解就和<bean>标签里面的属性作用是一样的
		AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
		//本例中 qualifiers 传入的是 null,qualifiers就是用来决定接口的实现类的
		if (qualifiers != null) {
			for (Class<? extends Annotation> qualifier : qualifiers) {
				if (Primary.class == qualifier) {
					abd.setPrimary(true);
				}
				else if (Lazy.class == qualifier) {
					abd.setLazyInit(true);
				}
				else {
					abd.addQualifier(new AutowireCandidateQualifier(qualifier));
				}
			}
		}
		//主要提供对BeanDefinition的一些定制化操作
		if (customizers != null) {
			for (BeanDefinitionCustomizer customizer : customizers) {
				customizer.customize(abd);
			}
		}
		//用 BeanDefinitionHolder 包装 BeanDefinition
		BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
		//此行代码与动态代理和 scope 注解有关,主要看看是否依照Spring的scope生成动态代理对象
		// 但是在本案例中没有做任何操作,只是返回了传入的 definitionHolder
		definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
		//向容器注册扫描到的Bean
		BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
	}
}
  • 1、将类转换为AnnotatedGenericBeanDefinition。
  • 2、调用conditionEvaluator的shouldSkip判断是否需要过滤,shouldSkip方法中先判断类上是否有Conditional注解,只处理有Conditional注解或其衍生注解的情况。
  • 3、获取beanName,如果我们设置了value则取其值,如果没有设置,底层上是调用JDK的Introspector.decapitalize方法,比如类名是HelloWorld,则对应的beanName是helloWorld。
  • 4、调用AnnotationConfigUtils.processCommonDefinitionAnnotations,获取Lazy、Primary、DependsOn等注解的值。
  • 5、最后调用BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry)将这个BeanDefinition注册到registry中,这里的注册和xml方式的注册一模一样。

使用AnnotationConfigUtils的processCommonDefinitionAnnotations方法处理注解Bean定义类中通用的注解

二、不是被@Configuration标记的Bean(即普通的业务Bean)的资源定位、加载、解析、注册分析

public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {

	public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
		//调用默认无参构造器,主要初始化AnnotatedBeanDefinitionReader
		// 以及路径扫描器ClassPathBeanDefinitionScanner
		this();
		//把传入的Class进行注册,Class既可以有@Configuration注解,也可以没有@Configuration注解
		//如何注册委托给了 org.springframework.context.annotation.AnnotatedBeanDefinitionReader.register 方法进行注册
		// 包装传入的Class 生成 BeanDefinition , 注册到BeanDefinitionRegistry
		register(componentClasses);

		//@Controller、@Service、@Component、@Repository标记的类在此方法被注册进IOC容器
		refresh();
	}
}

针对普通的业务Bean,即@Controller、@Service、@Component、@Repository标记的类是在AnnotationConfigApplicationContext构造函数中的refresh()方法的时候才会被注册进IOC容器,这和XML解析方式一样是调用的AbstractApplicationContext中的refresh()方法。

  • XML配置方式的解析配置并注册BeanDefinition实例时候,是调用的obtainFreshBeanFactory()方法。
  • 而注解方式是调用的invokeBeanFactoryPostProcessors(beanFactory)方法,在容器调用其后置处理器的时候会触发对普通的BeanDefinition的注册。
public abstract class AbstractApplicationContext extends DefaultResourceLoader
		implements ConfigurableApplicationContext {

	/**
	 * 加载或刷新一个持久化的配置,可能是XML文件、属性文件或关系数据库模式。
	 * 由于这是一种启动方法,如果失败,应该销毁已经创建的单例,以避免悬空资源。
	 * 换句话说,在调用该方法之后,要么全部实例化,要么完全不实例化。
	 * @throws BeansException 如果bean工厂无法初始化,则抛出 BeansException 异常
	 * @throws IllegalStateException 如果已经初始化且不支持多次刷新,则会抛出 IllegalStateException 异常
	 */
	@Override
	public void refresh() throws BeansException, IllegalStateException {
		// 给容器refresh加锁,避免容器处在refresh阶段时,容器进行了初始化或者销毁的操作
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.
			// 调用容器准备刷新的方法,获取容器的当时时间,同时给容器设置同步标识,具体方法
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			//告诉子类启动refreshBeanFactory()方法,Bean定义资源文件的载入从
			//子类的refreshBeanFactory()方法启动,里面有抽象方法
			//针对xml配置,最终创建内部容器,该容器负责 Bean 的创建与管理,此步会进行BeanDefinition的注册
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			// 注册一些容器中需要的系统Bean.例如classloader,beanfactoryPostProcessor等
			prepareBeanFactory(beanFactory);

			try {
				// Allows post-processing of the bean factory in context subclasses.
				//允许容器的子类去注册postProcessor  ,钩子方法
				postProcessBeanFactory(beanFactory);

				// Invoke factory processors registered as beans in the context.
				// 激活在容器中注册为bean的BeanFactoryPostProcessors
				//对于注解容器,org.springframework.context.annotation.ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry
				//方法扫描应用中所有BeanDefinition并注册到容器之中
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				// 注册拦截bean创建过程的BeanPostProcessor
				registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.
				// 找到“messageSource”的Bean提供给ApplicationContext使用,
				// 使得ApplicationContext具有国际化能力。
				initMessageSource();

				// Initialize event multicaster for this context.
				// 初始化ApplicationEventMulticaster该类作为事件发布者,
				// 可以存储所有事件监听者信息,并根据不同的事件,通知不同的事件监听者。
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				// 预留给 AbstractApplicationContext 的子类用于初始化其他特殊的 bean,
				// 该方法需要在所有单例 bean 初始化之前调用
				// 比如Web容器就会去初始化一些和主题展示相关的Bean(ThemeSource)
				onRefresh();

				// Check for listener beans and register them.
				// 注册监听器(检查监听器的bean并注册它们)
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.
				//设置自定义的类型转化器ConversionService,
				// 设置自定义AOP相关的类LoadTimeWeaverAware,
				// 清除临时的ClassLoader
				// ,实例化所有的类(懒加载的类除外)
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				// 初始化容器的生命周期事件处理器,(默认使用DefaultLifecycleProcessor),调用扩展了SmartLifecycle接口的start方法
				// 当Spring容器加载所有bean并完成初始化之后,会接着回调实现该接口的类中对应的方法(start()方法)
				// 并发布容器刷新完毕事件ContextRefreshedEvent给对应的事件监听者
				finishRefresh();
			}

			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				// Destroy already created singletons to avoid dangling resources.
				//销毁已创建的Bean
				destroyBeans();

				// Reset 'active' flag.
				//取消refresh操作,重置容器的同步标识
				cancelRefresh(ex);

				// Propagate exception to caller.
				throw ex;
			}

			finally {
				// Reset common introspection caches in Spring's core, since we
				// might not ever need metadata for singleton beans anymore...
				// 重置Spring内核中的共用的缓存,因为我们可能再也不需要单例bean的元数据了……
				resetCommonCaches();
			}
		}
	}
}

invokeBeanFactoryPostProcessors(beanFactory)方法中

  • 该方法会实例化和调用所有 BeanFactoryPostProcessor(包括其子类 BeanDefinitionRegistryPostProcessor)。
  • BeanFactoryPostProcessor 接口是 Spring 初始化 BeanFactory 时对外暴露的扩展点,Spring IoC 容器允许 BeanFactoryPostProcessor 在容器实例化任何 bean 之前读取 bean 的定义,并可以修改它。
  • BeanDefinitionRegistryPostProcessor 继承自 BeanFactoryPostProcessor,比 BeanFactoryPostProcessor 具有更高的优先级,主要用来在常规的 BeanFactoryPostProcessor 检测开始之前注册其他 bean 定义。特别是,你可以通过 BeanDefinitionRegistryPostProcessor 来注册一些常规的 BeanFactoryPostProcessor,因为此时所有常规的 BeanFactoryPostProcessor 都还没开始被处理。

 

注:这边的 “常规 BeanFactoryPostProcessor” 主要用来跟 BeanDefinitionRegistryPostProcessor 区分。

 

接着深入invokeBeanFactoryPostProcessors(beanFactory)方法

public abstract class AbstractApplicationContext extends DefaultResourceLoader
		implements ConfigurableApplicationContext {

	/**
	 * 实例化并调用所有已注册的BeanFactoryPostProcessor 的 bean,如果已给出顺序,请按照顺序。
	 * 必须在单实例实例化之前调用。
	 * Instantiate and invoke all registered BeanFactoryPostProcessor beans,
	 * respecting explicit order if given.
	 * <p>Must be called before singleton instantiation.
	 */
	protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		// 1.getBeanFactoryPostProcessors(): 拿到当前应用上下文beanFactoryPostProcessors变量中的值
		// 2.invokeBeanFactoryPostProcessors: 实例化并调用所有已注册的BeanFactoryPostProcessor
		PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

		// 如何找到一个LoadTimeWeaver,那么就准备将后置处理器“织入”bean工厂
		// (例如,一个 @Bean 方法通过ConfigurationClassPostProcessor来注册)
		// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
		// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
		if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}
	}
}

1、拿到当前应用上下文 beanFactoryPostProcessors 变量中的值。

public abstract class AbstractApplicationContext extends DefaultResourceLoader
		implements ConfigurableApplicationContext {

	//应用于刷新的 BeanFactoryPostProcessors,这个List用于存放Bean工厂处理器(BeanFactoryPostProcessor)
	private final List<BeanFactoryPostProcessor> beanFactoryPostProcessors = new ArrayList<>();

	//返回将应用到内部BeanFactory的BeanFactoryPostProcessors列表
	public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
		return this.beanFactoryPostProcessors;
	}
}

这边 getBeanFactoryPostProcessors() 会拿到当前应用上下文中已经注册的 BeanFactoryPostProcessor,在默认情况下,this.beanFactoryPostProcessors 是返回空的。

如何添加自定义 BeanFactoryPostProcessor 到 this.beanFactoryPostProcessors 变量中?

新建一个 ApplicationContextInitializer 的实现类 SpringApplicationContextInitializer ,并在 initialize 方法中写我们的逻辑。

public class MyApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
 
    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        FirstBeanDefinitionRegistryPostProcessor firstBeanDefinitionRegistryPostProcessor = new FirstBeanDefinitionRegistryPostProcessor();
        // 将自定义的firstBeanDefinitionRegistryPostProcessor添加到应用上下文中
        applicationContext.addBeanFactoryPostProcessor(firstBeanDefinitionRegistryPostProcessor);
        // ...自定义操作
        System.out.println("MyApplicationContextInitializer#initialize");
    }
}

1、Spring实现方式

将 SpringApplicationContextInitializer 作为初始化参数 contextInitializerClasses 配置到 web.xml 中。

<context-param>
    <param-name>contextInitializerClasses</param-name>
    <param-value>
        com.yibo.spring.MyApplicationContextInitializer
    </param-value>
</context-param>

这样,在启动应用时,FirstBeanDefinitionRegistryPostProcessor 就会被添加到 this.beanFactoryPostProcessors 中。

2、SpringBoot方式

2.1、mian函数中添加

@SpringBootApplication
public class MySpringBootApplication {
    public static void main(String[] args) {
        SpringApplication application = new SpringApplication(MySpringBootApplication.class);
        application.addInitializers(new MyApplicationContextInitializer());
        application.run(args);
    }
}

2.2、配置文件中配置

context.initializer.classes= com.yibo.spring.MyApplicationContextInitializer

2.3、SpringBoot的SPI扩展---META-INF/spring.factories中配置

在项目下的resources下新建META-INF文件夹,文件夹下新建spring.factories文件

org.springframework.context.ApplicationContextInitializer= com.yibo.spring.MyApplicationContextInitializer

给 MyApplicationContextInitializer 加上Order注解:我们指定其拥有最高的排序级别。(越高越早执行)

@Order(Ordered.HIGHEST_PRECEDENCE)
public class MyApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
 
    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        FirstBeanDefinitionRegistryPostProcessor firstBeanDefinitionRegistryPostProcessor = new FirstBeanDefinitionRegistryPostProcessor();
        // 将自定义的firstBeanDefinitionRegistryPostProcessor添加到应用上下文中
        applicationContext.addBeanFactoryPostProcessor(firstBeanDefinitionRegistryPostProcessor);
        // ...自定义操作
        System.out.println("MyApplicationContextInitializer#initialize");
    }
}

2、实例化并调用所有已注册的 BeanFactoryPostProcessor

深入PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors())

final class PostProcessorRegistrationDelegate {

	/**
	 * 调用BeanFactoryPostProcessor
	 * 主要是分情况处理不同类型的BeanFactoryPostProcessors。
	 * BeanFacotryPostProcessors主要分为两类,一类是BeanDefinitionRegistry的BeanFactoryPostProcessor,另外一类是常规的BeanFactoryPostProcessor。
	 * 优先处理前者。同时,这两种后置处理器又被分为从参数里传入和从容器里获取的,最终要将从参数里获取的和从容器里获取的合并在一起。
	 * 合并的时候又分为实现了PriorityOrder和普通Order以及没有实现这两个接口的,实现了PriorityOrdered的先执行,
	 * 同时是按照PriorityOrdered顺序执行的,其次再到Order,按照Order执行,最后才是没实现这两个接口的,
	 * 先执行完BeanDefinitionRegistryPostProcessor的invokeBeanDefinitionRegistryPostProcessors方法,
	 * 再对BeanDefinitionRegistryPostProcessor执行invokeBeanFactoryPostProcessors方法,
	 * 之后再对常规的BeanFacotryPostProcessors执行invokeBeanFactoryPostProcessors方法
	 * @参数 beanFactory 应用上下文的 BeanFactory 实例
	 * @参数 beanFactoryPostProcessors 应用上下文指定要执行的 BeanFactoryPostProcessor
	 **/
	public static void invokeBeanFactoryPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

		// Invoke BeanDefinitionRegistryPostProcessors first, if any.
		// 如果有BeanDefinitionRegistryPostProcessor的话优先执行
		Set<String> processedBeans = new HashSet<>();

		// 1.判断beanFactory是否为BeanDefinitionRegistry,beanFactory为DefaultListableBeanFactory,
		// 而DefaultListableBeanFactory实现了BeanDefinitionRegistry接口,因此这边为true
		if (beanFactory instanceof BeanDefinitionRegistry) {
			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
			// 用于存放普通的BeanFactoryPostProcessor
			List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
			// 用于存放BeanDefinitionRegistryPostProcessor
			List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

			// 2.首先处理入参中的beanFactoryPostProcessors
			// 遍历所有的beanFactoryPostProcessors, 将BeanDefinitionRegistryPostProcessor和普通BeanFactoryPostProcessor区分开
			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
					// 2.1 如果是BeanDefinitionRegistryPostProcessor
					BeanDefinitionRegistryPostProcessor registryProcessor =
							(BeanDefinitionRegistryPostProcessor) postProcessor;
					// 2.1.1 直接执行BeanDefinitionRegistryPostProcessor接口的postProcessBeanDefinitionRegistry方法
					registryProcessor.postProcessBeanDefinitionRegistry(registry);
					// 2.1.2 添加到registryProcessors(用于最后执行postProcessBeanFactory方法)
					registryProcessors.add(registryProcessor);
				}
				else {
					// 2.2 否则,只是普通的BeanFactoryPostProcessor
					// 2.2.1 添加到regularPostProcessors(用于最后执行postProcessBeanFactory方法)
					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.
			// 用于保存本次要执行的BeanDefinitionRegistryPostProcessor
			List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

			// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
			// 3.调用所有实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessor实现类
			// 3.1 找出所有实现BeanDefinitionRegistryPostProcessor接口的Bean的beanName
			String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			// 3.2 遍历postProcessorNames
			for (String ppName : postProcessorNames) {
				// 3.3 校验是否实现了PriorityOrdered接口
				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
					// 3.4 获取ppName对应的bean实例, 添加到currentRegistryProcessors中,
					// beanFactory.getBean: 这边getBean方法会触发创建ppName对应的bean对象, 目前暂不深入解析
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					// 3.5 将要被执行的加入processedBeans,避免后续重复执行
					processedBeans.add(ppName);
				}
			}
			// 3.6 进行排序(根据是否实现PriorityOrdered、Ordered接口和order值来排序)
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			// 3.7 添加到registryProcessors(用于最后执行postProcessBeanFactory方法)
			registryProcessors.addAll(currentRegistryProcessors);
			// 3.8 遍历currentRegistryProcessors, 执行postProcessBeanDefinitionRegistry方法
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			// 3.9 执行完毕后, 清空currentRegistryProcessors
			currentRegistryProcessors.clear();

			// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
			// 4.调用所有实现了Ordered接口的BeanDefinitionRegistryPostProcessor实现类(过程跟上面的步骤3基本一样)
			// 4.1 找出所有实现BeanDefinitionRegistryPostProcessor接口的类, 这边重复查找是因为执行完上面的BeanDefinitionRegistryPostProcessor,
			// 可能会新增了其他的BeanDefinitionRegistryPostProcessor, 因此需要重新查找
			postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				// 校验是否实现了Ordered接口,并且还未执行过
				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);
			// 4.2 遍历currentRegistryProcessors, 执行postProcessBeanDefinitionRegistry方法
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			currentRegistryProcessors.clear();

			// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
			// 5.最后, 调用所有剩下的BeanDefinitionRegistryPostProcessors
			boolean reiterate = true;
			while (reiterate) {
				reiterate = false;
				// 5.1 找出所有实现BeanDefinitionRegistryPostProcessor接口的类
				postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
				for (String ppName : postProcessorNames) {
					// 5.2 跳过已经执行过的
					if (!processedBeans.contains(ppName)) {
						currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
						processedBeans.add(ppName);
						// 5.3 如果有BeanDefinitionRegistryPostProcessor被执行, 则有可能会产生新的BeanDefinitionRegistryPostProcessor,
						// 因此这边将reiterate赋值为true, 代表需要再循环查找一次
						reiterate = true;
					}
				}
				sortPostProcessors(currentRegistryProcessors, beanFactory);
				registryProcessors.addAll(currentRegistryProcessors);
				// 5.4 遍历currentRegistryProcessors, 执行postProcessBeanDefinitionRegistry方法
				invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
				currentRegistryProcessors.clear();
			}

			// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
			// 6.调用所有BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法(BeanDefinitionRegistryPostProcessor继承自BeanFactoryPostProcessor)
			invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
			// 7.最后, 调用入参beanFactoryPostProcessors中的普通BeanFactoryPostProcessor的postProcessBeanFactory方法
			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!
		// 到这里 , 入参beanFactoryPostProcessors和容器中的所有BeanDefinitionRegistryPostProcessor已经全部处理完毕,
		// 下面开始处理容器中的所有BeanFactoryPostProcessor
		// 8.找出所有实现BeanFactoryPostProcessor接口的类
		String[] postProcessorNames =
				beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

		// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
		// Ordered, and the rest.
		// 用于存放实现了PriorityOrdered接口的BeanFactoryPostProcessor
		List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		// 用于存放实现了Ordered接口的BeanFactoryPostProcessor的beanName
		List<String> orderedPostProcessorNames = new ArrayList<>();
		// 用于存放普通BeanFactoryPostProcessor的beanName
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
		// 8.1 遍历postProcessorNames, 将BeanFactoryPostProcessor按实现PriorityOrdered、实现Ordered接口、普通三种区分开
		for (String ppName : postProcessorNames) {
			// 8.2 跳过已经执行过的
			if (processedBeans.contains(ppName)) {
				// skip - already processed in first phase above
			}
			else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				// 8.3 添加实现了PriorityOrdered接口的BeanFactoryPostProcessor
				priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
			}
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				// 8.4 添加实现了Ordered接口的BeanFactoryPostProcessor的beanName
				orderedPostProcessorNames.add(ppName);
			}
			else {
				// 8.5 添加剩下的普通BeanFactoryPostProcessor的beanName
				nonOrderedPostProcessorNames.add(ppName);
			}
		}

		// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
		// 9.调用所有实现PriorityOrdered接口的BeanFactoryPostProcessor
		// 9.1 对priorityOrderedPostProcessors排序
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		// 9.2 遍历priorityOrderedPostProcessors, 执行postProcessBeanFactory方法
		invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

		// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
		// 10.调用所有实现Ordered接口的BeanFactoryPostProcessor
		List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
		for (String postProcessorName : orderedPostProcessorNames) {
			// 10.1 获取postProcessorName对应的bean实例, 添加到orderedPostProcessors, 准备执行
			orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		// 10.2 对orderedPostProcessors排序
		sortPostProcessors(orderedPostProcessors, beanFactory);
		// 10.3 遍历orderedPostProcessors, 执行postProcessBeanFactory方法
		invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

		// Finally, invoke all other BeanFactoryPostProcessors.
		// 11.调用所有剩下的BeanFactoryPostProcessor
		List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
		for (String postProcessorName : nonOrderedPostProcessorNames) {
			// 11.1 获取postProcessorName对应的bean实例, 添加到nonOrderedPostProcessors, 准备执行
			nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		// 11.2 遍历nonOrderedPostProcessors, 执行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...
		// 12.清除元数据缓存(mergedBeanDefinitions、allBeanNamesByType、singletonBeanNamesByType),
		// 因为后处理器可能已经修改了原始元数据,例如, 替换值中的占位符...
		beanFactory.clearMetadataCache();
	}
}

调用invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry)进行BeanDefinition的注册

private static void invokeBeanDefinitionRegistryPostProcessors(
		Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {

	for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
		postProcessor.postProcessBeanDefinitionRegistry(registry);
	}
}

上一步每一个BeanDefinitionRegistryPostProcessor都会调用postProcessBeanDefinitionRegistry(registry)进行处理,继续深入该方法

public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor,
		PriorityOrdered, ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware {

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

通过上面发现,BeanDefinition实例的注册是通过ConfigurationClassPostProcessor类的后置处理方法processConfigBeanDefinitions(registry);方法来处理。

继续深入processConfigBeanDefinitions(registry)方法

public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor,
		PriorityOrdered, ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware {

	public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
		//1.初始化BeanDefinitionHolder集合
		List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
		//2.所有已经注册的bean
		String[] candidateNames = registry.getBeanDefinitionNames();

		//3.遍历已注册的bean数组
		for (String beanName : candidateNames) {
			//得到BeanDefinition实例
			BeanDefinition beanDef = registry.getBeanDefinition(beanName);
			if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
				//如果BeanDefinition 中的configurationClass 属性为full 或者lite ,则意味着已经处理过了,直接跳过
				if (logger.isDebugEnabled()) {
					logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
				}
			}
			else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
				//带有@Configuration注解的bean添加到集合中
				// 判断对应bean是否为配置类,如果是,则加入到configCandidates
				configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
			}
		}

		// Return immediately if no @Configuration classes were found
		if (configCandidates.isEmpty()) {
			//两种都不满足,配置类已经被处理了
			return;
		}

		// Sort by previously determined @Order value, if applicable
		// 对configCandidates 进行 排序,按照@Order 配置的值进行排序
		configCandidates.sort((bd1, bd2) -> {
			int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
			int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
			return Integer.compare(i1, i2);
		});

		// Detect any custom bean name generation strategy supplied through the enclosing application context
		// 如果BeanDefinitionRegistry 是SingletonBeanRegistry 的子类的话,
		// 由于我们当前传入的是DefaultListableBeanFactory,它是
		// SingletonBeanRegistry 的子类。因此会将registry强转为SingletonBeanRegistry
		SingletonBeanRegistry sbr = null;
		if (registry instanceof SingletonBeanRegistry) {
			sbr = (SingletonBeanRegistry) registry;
			if (!this.localBeanNameGeneratorSet) {
				BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(
						AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR);
				if (generator != null) {
					this.componentScanBeanNameGenerator = generator;
					this.importBeanNameGenerator = generator;
				}
			}
		}

		//web应用为StandardServletEnvironment
		if (this.environment == null) {
			this.environment = new StandardEnvironment();
		}

		// Parse each @Configuration class
		//初始化一个ConfigurationClassParser解析器,可以解析@Congiguration配置类
		ConfigurationClassParser parser = new ConfigurationClassParser(
				this.metadataReaderFactory, this.problemReporter, this.environment,
				this.resourceLoader, this.componentScanBeanNameGenerator, registry);
		//List转成Set
		Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
		//初始化一个已经解析的HashSet
		Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
		//循环解析,直到candidates为空
		do {
			//核心:解析
			parser.parse(candidates);
			//主要校验配置类不能使用final修饰符(CGLIB代理是生成一个子类,因此原先的类不能使用final修饰)
			//if (this.getMetadata().isAnnotated(Configuration.class.getName()) && this.getMetadata().isFinal())
			parser.validate();
			//排除已处理过的配置类
			Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
			configClasses.removeAll(alreadyParsed);

			// Read the model and create bean definitions based on its content
			//读取模型并根据其内容创建bean定义
			if (this.reader == null) {
				this.reader = new ConfigurationClassBeanDefinitionReader(
						registry, this.sourceExtractor, this.resourceLoader, this.environment,
						this.importBeanNameGenerator, parser.getImportRegistry());
			}
			//2.加载bean定义信息,主要实现将@Configuration @Import @ImportResource @ImportRegistrar注册为bean
			this.reader.loadBeanDefinitions(configClasses);
			//将configClasses加入到已解析alreadyParsed中
			alreadyParsed.addAll(configClasses);
			//清空已处理的配置类
			candidates.clear();
			//再次获取容器中bean定义数量  如果大于 之前获取的bean定义数量,则说明有新的bean注册到容器中,需要再次解析
			//getBeanDefinitionCount()取得是registry.beanDefinitionMap.size()
			if (registry.getBeanDefinitionCount() > candidateNames.length) {
				//容器中新的所有已注册的bean(包括老的)
				String[] newCandidateNames = registry.getBeanDefinitionNames();
				//容器中老的已注册的bean(已经解析了)
				Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
				//用来存储已经解析的类
				Set<String> alreadyParsedClasses = new HashSet<>();
				//循环遍历把已解析的类放到alreadyParsedClasses中
				for (ConfigurationClass configurationClass : alreadyParsed) {
					alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
				}

				//循环遍历新的所有已注册的bean,排除老的已解析的,再过滤是否是配置类带有@Configuration,并且没有解析过,添加到candidates中,
				//下一次可以再处理解析
				for (String candidateName : newCandidateNames) {
					if (!oldCandidateNames.contains(candidateName)) {
						BeanDefinition bd = registry.getBeanDefinition(candidateName);
						if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
								!alreadyParsedClasses.contains(bd.getBeanClassName())) {
							candidates.add(new BeanDefinitionHolder(bd, candidateName));
						}
					}
				}
				candidateNames = newCandidateNames;
			}
		}
		while (!candidates.isEmpty());

		// Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
		if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
			sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
		}

		if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
			// Clear cache in externally provided MetadataReaderFactory; this is a no-op
			// for a shared cache since it'll be cleared by the ApplicationContext.
			((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
		}
	}
}

parser.parse(candidates)对配置类的解析

class ConfigurationClassParser {

	private final DeferredImportSelectorHandler deferredImportSelectorHandler = new DeferredImportSelectorHandler();

	public void parse(Set<BeanDefinitionHolder> configCandidates) {
		//循环遍历需要处理的配置类
		for (BeanDefinitionHolder holder : configCandidates) {
			BeanDefinition bd = holder.getBeanDefinition();

			//根据BeanDefinition实例判断调用哪个,其实最后还是调用
			//核心方法:processConfigurationClass(ConfigurationClass configClass)
			try {
				if (bd instanceof AnnotatedBeanDefinition) {
					parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
				}
				else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {
					parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());
				}
				else {
					parse(bd.getBeanClassName(), holder.getBeanName());
				}
			}
			catch (BeanDefinitionStoreException ex) {
				throw ex;
			}
			catch (Throwable ex) {
				throw new BeanDefinitionStoreException(
						"Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex);
			}
		}

		//字面理解:处理延迟导入的javabean
		//parse方法,把被处理的类实现DeferredImportSelector接口,加入deferredImportSelectors集合中,
		//处理deferredImportSelectors集合种类
		this.deferredImportSelectorHandler.process();
	}
}

继续深入其中的一个parse()方法

class ConfigurationClassParser {

	protected final void parse(@Nullable String className, String beanName) throws IOException {
		Assert.notNull(className, "No bean class name for configuration class bean definition");
		MetadataReader reader = this.metadataReaderFactory.getMetadataReader(className);
		processConfigurationClass(new ConfigurationClass(reader, beanName), DEFAULT_EXCLUSION_FILTER);
	}

	protected final void parse(Class<?> clazz, String beanName) throws IOException {
		processConfigurationClass(new ConfigurationClass(clazz, beanName), DEFAULT_EXCLUSION_FILTER);
	}

	protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException {
		processConfigurationClass(new ConfigurationClass(metadata, beanName), DEFAULT_EXCLUSION_FILTER);
	}
}

parse调用核心方法processConfigurationClass(ConfigurationClass configClass)解析

class ConfigurationClassParser {

	protected void processConfigurationClass(ConfigurationClass configClass, Predicate<String> filter) throws IOException {
		//检查当前解析的配置bean是否包含Conditional注解,如果不包含则不需要跳过
		// 如果包含了则进行match方法得到匹配结果,如果是符合的并且设置的配置解析策略是解析阶段不需要调过
		if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
			return;
		}

		//在这里处理Configuration重复import
		//如果同一个配置类被处理两次,两次都属于被import的则合并导入类,返回。如果配置类不是被导入的,则移除旧使用新的配置类
		ConfigurationClass existingClass = this.configurationClasses.get(configClass);
		if (existingClass != null) {
			if (configClass.isImported()) {
				if (existingClass.isImported()) {
					existingClass.mergeImportedBy(configClass);
				}
				// Otherwise ignore new imported config class; existing non-imported class overrides it.
				return;
			}
			else {
				// Explicit bean definition found, probably replacing an import.
				// Let's remove the old one and go with the new one.
				this.configurationClasses.remove(configClass);
				this.knownSuperclasses.values().removeIf(configClass::equals);
			}
		}

		// Recursively process the configuration class and its superclass hierarchy.
		SourceClass sourceClass = asSourceClass(configClass, filter);
		//递归解析
		do {
			sourceClass = doProcessConfigurationClass(configClass, sourceClass, filter);
		}
		while (sourceClass != null);

		// 添加到ConfigurationClassParser的configurationClasses中
		this.configurationClasses.put(configClass, configClass);
	}
}

递归解析,调用doProcessConfigurationClass方法,终于到了解析的地方,继续深入

class ConfigurationClassParser {

	protected final SourceClass doProcessConfigurationClass(
			ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter)
			throws IOException {

		if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
			// Recursively process any member (nested) classes first 处理内部类
			processMemberClasses(configClass, sourceClass, filter);
		}

		// Process any @PropertySource annotations
		// 处理@PropertySource注解
		for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
				sourceClass.getMetadata(), PropertySources.class,
				org.springframework.context.annotation.PropertySource.class)) {
			if (this.environment instanceof ConfigurableEnvironment) {
				processPropertySource(propertySource);
			}
			else {
				logger.info("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
						"]. Reason: Environment must implement ConfigurableEnvironment");
			}
		}

		// Process any @ComponentScan annotations
		// 处理@ComponentScan注解
		Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
				sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
		if (!componentScans.isEmpty() &&
				!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
			//扫描
			for (AnnotationAttributes componentScan : componentScans) {
				// The config class is annotated with @ComponentScan -> perform the scan immediately
				Set<BeanDefinitionHolder> scannedBeanDefinitions =
						this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
				// Check the set of scanned definitions for any further config classes and parse recursively if needed
				//遍历扫描到的配置类进行递归解析
				for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
					BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
					if (bdCand == null) {
						bdCand = holder.getBeanDefinition();
					}
					if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
						parse(bdCand.getBeanClassName(), holder.getBeanName());
					}
				}
			}
		}

		// Process any @Import annotations
		// 处理@Import注解
		processImports(configClass, sourceClass, getImports(sourceClass), filter, true);

		// Process any @ImportResource annotations
		// 处理@ImportResource 注解
		AnnotationAttributes importResource =
				AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
		if (importResource != null) {
			String[] resources = importResource.getStringArray("locations");
			Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
			// 遍历配置的locations,加入到configClass 中的ImportedResource
			for (String resource : resources) {
				String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
				configClass.addImportedResource(resolvedResource, readerClass);
			}
		}

		// Process individual @Bean methods
		// 处理@Bean修饰的方法
		Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
		for (MethodMetadata methodMetadata : beanMethods) {
			configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
		}

		// Process default methods on interfaces
		// 处理接口定义的方法
		processInterfaces(configClass, sourceClass);

		// Process superclass, if any
		if (sourceClass.getMetadata().hasSuperClass()) {
			String superclass = sourceClass.getMetadata().getSuperClassName();
			if (superclass != null && !superclass.startsWith("java") &&
					!this.knownSuperclasses.containsKey(superclass)) {
				this.knownSuperclasses.put(superclass, configClass);
				// Superclass found, return its annotation metadata and recurse
				return sourceClass.getSuperClass();
			}
		}

		// No superclass -> processing is complete
		return null;
	}
}

解析doProcessConfigurationClass方法,总结一下:

  • 1、处理内部类
  • 2、处理@PropertySource注解
  • 3、处理@ComponentScan注解
  • 4、处理@Import注解
  • 5、处理@ImportResource注解
  • 6、处理@Bean修饰的方法
  • 7、处理接口定义的方法
  • 8、处理父类

1、处理内部类(递归解析)

class ConfigurationClassParser {

	/**
	 * Register member (nested) classes that happen to be configuration classes themselves.
	 * 处理内部类
	 */
	private void processMemberClasses(ConfigurationClass configClass, SourceClass sourceClass,
			Predicate<String> filter) throws IOException {
		//读取配置类中所有成员类
		Collection<SourceClass> memberClasses = sourceClass.getMemberClasses();
		if (!memberClasses.isEmpty()) {
			List<SourceClass> candidates = new ArrayList<>(memberClasses.size());
			for (SourceClass memberClass : memberClasses) {
				//过滤出配置类
				if (ConfigurationClassUtils.isConfigurationCandidate(memberClass.getMetadata()) &&
						!memberClass.getMetadata().getClassName().equals(configClass.getMetadata().getClassName())) {
					candidates.add(memberClass);
				}
			}
			//根据Order进行排序
			OrderComparator.sort(candidates);
			//遍历
			for (SourceClass candidate : candidates) {
				//出现配置类循环导入,直接报错
				if (this.importStack.contains(configClass)) {
					this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));
				}
				else {
					//将配置类入栈
					this.importStack.push(configClass);
					try {
						//处理配置类
						processConfigurationClass(candidate.asConfigClass(configClass), filter);
					}
					finally {
						//解析完出栈
						this.importStack.pop();
					}
				}
			}
		}
	}
}

2、处理@PropertySource注解

如果配置类上有@PropertySource注解,则解析加载properties文件,并将属性添加到Spring上下文中。 深入processPropertySource(propertySource)方法

class ConfigurationClassParser {

	private void processPropertySource(AnnotationAttributes propertySource) throws IOException {
		String name = propertySource.getString("name");
		if (!StringUtils.hasLength(name)) {
			name = null;
		}
		String encoding = propertySource.getString("encoding");
		if (!StringUtils.hasLength(encoding)) {
			encoding = null;
		}
		String[] locations = propertySource.getStringArray("value");
		Assert.isTrue(locations.length > 0, "At least one @PropertySource(value) location is required");
		boolean ignoreResourceNotFound = propertySource.getBoolean("ignoreResourceNotFound");

		Class<? extends PropertySourceFactory> factoryClass = propertySource.getClass("factory");
		PropertySourceFactory factory = (factoryClass == PropertySourceFactory.class ?
				DEFAULT_PROPERTY_SOURCE_FACTORY : BeanUtils.instantiateClass(factoryClass));

		for (String location : locations) {
			try {
				String resolvedLocation = this.environment.resolveRequiredPlaceholders(location);
				Resource resource = this.resourceLoader.getResource(resolvedLocation);
				addPropertySource(factory.createPropertySource(name, new EncodedResource(resource, encoding)));
			}
			catch (IllegalArgumentException | FileNotFoundException | UnknownHostException ex) {
				// Placeholders not resolvable or resource not found when trying to open it
				if (ignoreResourceNotFound) {
					if (logger.isInfoEnabled()) {
						logger.info("Properties location [" + location + "] not resolvable: " + ex.getMessage());
					}
				}
				else {
					throw ex;
				}
			}
		}
	}

	private void addPropertySource(PropertySource<?> propertySource) {
		String name = propertySource.getName();
		MutablePropertySources propertySources = ((ConfigurableEnvironment) this.environment).getPropertySources();

		//如果存在同名的PropertySource,
		// 则使用CompositePropertySource替换原来的PropertySource,
		// 而CompositePropertySource中包含了所有的PropertySource
		if (this.propertySourceNames.contains(name)) {
			// We've already added a version, we need to extend it
			PropertySource<?> existing = propertySources.get(name);
			if (existing != null) {
				PropertySource<?> newSource = (propertySource instanceof ResourcePropertySource ?
						((ResourcePropertySource) propertySource).withResourceName() : propertySource);
				if (existing instanceof CompositePropertySource) {
					//将新的PropertySource添加到第一个,使用时在该组中最后一个使用。
					((CompositePropertySource) existing).addFirstPropertySource(newSource);
				}
				else {
					if (existing instanceof ResourcePropertySource) {
						existing = ((ResourcePropertySource) existing).withResourceName();
					}
					CompositePropertySource composite = new CompositePropertySource(name);
					composite.addPropertySource(newSource);
					composite.addPropertySource(existing);
					propertySources.replace(name, composite);
				}
				return;
			}
		}

		/**
		 * 如果没有同名的PropertySource,当只有一个的时候,直接添加到propertySources中
		 * 否则将新的PropertySource添加到除systemProperties
		 * systemEnvironment变量紧接着的第一个(意思就是后添加的后使用,但是如果他们存在同名的属性,后使用的PropertySource会覆盖先使用的)
		 */
		if (this.propertySourceNames.isEmpty()) {
			propertySources.addLast(propertySource);
		}
		else {
			/**
			 * propertySourceNames中存放的是自定义的PropertySource name,不包含systemProperties systemEnvironment
			 * 因此每次添加的新PropertySource都是在列表中的第三个(得出此结论的前提框架不在添加其他默认的PropertySource)
			 */
			String firstProcessed = this.propertySourceNames.get(this.propertySourceNames.size() - 1);
			propertySources.addBefore(firstProcessed, propertySource);
		}
		this.propertySourceNames.add(name);
	}
}

3、处理@ComponentScan注解

获取配置类上的@ComponentScan注解,判断是否需要跳过。循环所有的ComponentScan,立即执行扫描。

// Process any @ComponentScan annotations
// 处理@ComponentScan注解
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
		sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
if (!componentScans.isEmpty() &&
		!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
	//扫描
	for (AnnotationAttributes componentScan : componentScans) {
		// The config class is annotated with @ComponentScan -> perform the scan immediately
		Set<BeanDefinitionHolder> scannedBeanDefinitions =
				this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
		// Check the set of scanned definitions for any further config classes and parse recursively if needed
		//遍历扫描到的配置类进行递归解析
		for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
			BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
			if (bdCand == null) {
				bdCand = holder.getBeanDefinition();
			}
			//检验扫描获得的BeanDefinition中是否有配置类,如果有配置类,这里的配置类包括FullConfigurationClass和LiteConfigurationClass。
			//(也就是说只要有@Configuration、@Component、@ComponentScan、@Import、@ImportResource和@Bean中的其中一个注解),则递归调用parse方法,进行解析。
			if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
				parse(bdCand.getBeanClassName(), holder.getBeanName());
			}
		}
	}
}

继续深入分析

Set<BeanDefinitionHolder> scannedBeanDefinitions = this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
class ComponentScanAnnotationParser {

	private final Environment environment;

	private final ResourceLoader resourceLoader;

	private final BeanDefinitionRegistry registry;

	public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {
		//根据@ComponentScan的useDefaultFilters值来构建一个ClassPathBeanDefinitionScanner
		//默认为true  如果为true 会注册一些默认的注解过滤器,例如@Component @ManagedBean 和 @Named
		ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,
				componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);

		//类名生成器,默认为BeanNameGenerator接口
		Class<? extends BeanNameGenerator> generatorClass = componentScan.getClass("nameGenerator");
		boolean useInheritedGenerator = (BeanNameGenerator.class == generatorClass);
		//为scanner设置类名生成器,默认为AnnotationBeanNameGenerator  如果不填则为类名且首字母小写
		scanner.setBeanNameGenerator(useInheritedGenerator ? this.beanNameGenerator :
				BeanUtils.instantiateClass(generatorClass));

		ScopedProxyMode scopedProxyMode = componentScan.getEnum("scopedProxy");
		//scopedProxy默认为DEFAULT
		if (scopedProxyMode != ScopedProxyMode.DEFAULT) {
			scanner.setScopedProxyMode(scopedProxyMode);
		}
		else {
			//scopeResolver默认为AnnotationScopeMetadataResolver
			Class<? extends ScopeMetadataResolver> resolverClass = componentScan.getClass("scopeResolver");
			scanner.setScopeMetadataResolver(BeanUtils.instantiateClass(resolverClass));
		}
		//设置资源匹配器  默认为**/*.class   即所有class
		scanner.setResourcePattern(componentScan.getString("resourcePattern"));
		//找到所有的设置的filter 默认为空
		for (AnnotationAttributes filter : componentScan.getAnnotationArray("includeFilters")) {
			for (TypeFilter typeFilter : typeFiltersFor(filter)) {
				scanner.addIncludeFilter(typeFilter);
			}
		}

		//找到所有排除的filter ,springboot默认有TypeExcludeFilter和AutoConfigurationExcludeFilter
		for (AnnotationAttributes filter : componentScan.getAnnotationArray("excludeFilters")) {
			for (TypeFilter typeFilter : typeFiltersFor(filter)) {
				scanner.addExcludeFilter(typeFilter);
			}
		}
		//是否懒加载 默认为false
		boolean lazyInit = componentScan.getBoolean("lazyInit");
		if (lazyInit) {
			scanner.getBeanDefinitionDefaults().setLazyInit(true);
		}

		Set<String> basePackages = new LinkedHashSet<>();
		//找到所有的扫描路径
		String[] basePackagesArray = componentScan.getStringArray("basePackages");
		//解析每个路径 默认这儿为空
		for (String pkg : basePackagesArray) {
			//解析这些路径
			String[] tokenized = StringUtils.tokenizeToStringArray(this.environment.resolvePlaceholders(pkg),
					ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
			//将解析出来的路径添加到原有的路径中
			Collections.addAll(basePackages, tokenized);
		}
		//如果有basePackageClasses则添加  默认为null
		for (Class<?> clazz : componentScan.getClassArray("basePackageClasses")) {
			basePackages.add(ClassUtils.getPackageName(clazz));
		}
		//如果上述的全部为空  则添加声明类的所在包
		//这也就是为何@SpringbootApplication默认只解析其所在的包下面的所有的类,其上级包没法解决
		if (basePackages.isEmpty()) {
			basePackages.add(ClassUtils.getPackageName(declaringClass));
		}
		//将传入的类本身排除掉
		scanner.addExcludeFilter(new AbstractTypeHierarchyTraversingFilter(false, false) {
			@Override
			protected boolean matchClassName(String className) {
				return declaringClass.equals(className);
			}
		});

		//进行扫描
		return scanner.doScan(StringUtils.toStringArray(basePackages));
	}
}

这个方法很长,但内容很简单,无非就是挨个解析@ComponentScan的值并将其设置到ClassPathBeanDefinitionScanner中,然后调用scanner的解析方法,这儿有两点需要注意

  • 1、默认的includeFilter中加入了@Component注解,这个非常重要
  • 2、如果注解中没有找到任何可用的basePackage,那么会默认使用传入类的package作为basePackage,而这儿第一次进来的一般为主启动类,所以@springbootApplication之所以默认是解析其类所在的包下所有的类的缘由就在于此。

然后我们接着看doScan方法

public class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateComponentProvider {

	private BeanNameGenerator beanNameGenerator = AnnotationBeanNameGenerator.INSTANCE;

	private ScopeMetadataResolver scopeMetadataResolver = new AnnotationScopeMetadataResolver();

	protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
		//做下判空
		Assert.notEmpty(basePackages, "At least one base package must be specified");
		//创建返回set
		Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
		//迭代每个basePackage
		for (String basePackage : basePackages) {
			//找到basePackage下所有的配置类
			Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
			//处理这次找到的所有配置类
			for (BeanDefinition candidate : candidates) {
				//获取其Scope信息,也就是分析其@Scope注解
				ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
				//设置其scope
				candidate.setScope(scopeMetadata.getScopeName());
				//这儿会获取名字,如果没有默认为其类名且首字母小写
				String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
				//如果配置类的BeanDefinition继承了AbstractBeanDefinition
				if (candidate instanceof AbstractBeanDefinition) {
					//则为这个candidate根据刚才初始化时构建的beanDefinitionDefaults来设置BeanDefinition一些属性,
					//例如是否懒加载,自动装配模型等
					postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
				}
				//如果配置类 的BeanDefinition实现了AnnotatedBeanDefinition接口
				//例如有@Lazy  @Primary @DependsOn @Role @Description等注解
				if (candidate instanceof AnnotatedBeanDefinition) {
					//那么就对其每个注解进行特定的处理  例如Lazy设置懒加载
					// 例如Primary设置该类为主要类(例如一个接口有多个实现时,某个实现类加上这个就可以直接使用@Autowire注解不会报错)
					AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
				}
				//检查一下该配置类是否在registray中已存在。为true则代表无冲突,否则会报异常
				//例如两个类名一样且都使用@Component注解没有指定姓名就会报错这儿
				if (checkCandidate(beanName, candidate)) {
					//如果没问题则构造一个BeanDefinitionHolder
					BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
					//这儿是根据scope信息来判定是否需要需要生成代理  默认不生成
					//如果要生成可以为配置类加上@Scope(proxyMode = ScopedProxyMode.DEFAULT) 即可//只要不为ScopedProxyMode.NO(默认属性)即可
					definitionHolder =
							AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
					beanDefinitions.add(definitionHolder);
					//将该配置类注入到spring的registry中
					registerBeanDefinition(definitionHolder, this.registry);
				}
			}
		}
		return beanDefinitions;
	}
}

这个方法主要就是根据basePackage找到所有的配置类并创建BeanDefinition返回,然后为BeanDefinition设置一些必要的属性,最后根据特定的注解做一些特殊的判断即可。最后这些配置类代表的BeanDefinitionHolder 会被添加到spring的regitry中,在后面实例化的时候将会有很大的作用。

 

那我们还是接着看下basePackage下的Bean是如何被找到的,我们接着看findCandidateComponents方法。

public class ClassPathScanningCandidateComponentProvider implements EnvironmentCapable, ResourceLoaderAware {
	
	public Set<BeanDefinition> findCandidateComponents(String basePackage) {
		if (this.componentsIndex != null && indexSupportsIncludeFilters()) {
			return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);
		}
		else {
			return scanCandidateComponents(basePackage);
		}
	}

	private Set<BeanDefinition> scanCandidateComponents(String basePackage) {
		Set<BeanDefinition> candidates = new LinkedHashSet<>();
		try {
			//找到解析的路径匹配规则  resourcePattern默认为**/*.class   即所有的class
			String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
					resolveBasePackage(basePackage) + '/' + this.resourcePattern;
			//根据路径去循环递归查找路径所包含的每一个class文件
			Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);
			boolean traceEnabled = logger.isTraceEnabled();
			boolean debugEnabled = logger.isDebugEnabled();
			for (Resource resource : resources) {
				if (traceEnabled) {
					logger.trace("Scanning " + resource);
				}
				//循环处理每个可读的class文件
				if (resource.isReadable()) {
					try {
						//读取文件的元数据
						MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
						//如果文件在includeFilter中  且没有包含在excludeFilters中 则说明是我们需要加入到容器中的配置类
						if (isCandidateComponent(metadataReader)) {
							//新建ScannedGenericBeanDefinition  (注意其实现了AnnotatedBeanDefinition接口,且集成了AbstractBeanDefinition类)
							ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
							sbd.setSource(resource);
							if (isCandidateComponent(sbd)) {
								if (debugEnabled) {
									logger.debug("Identified candidate component class: " + resource);
								}
								candidates.add(sbd);
							}
							else {
								if (debugEnabled) {
									logger.debug("Ignored because not a concrete top-level class: " + resource);
								}
							}
						}
						else {
							if (traceEnabled) {
								logger.trace("Ignored because not matching any filter: " + resource);
							}
						}
					}
					catch (Throwable ex) {
						throw new BeanDefinitionStoreException(
								"Failed to read candidate component class: " + resource, ex);
					}
				}
				else {
					if (traceEnabled) {
						logger.trace("Ignored because not readable: " + resource);
					}
				}
			}
		}
		catch (IOException ex) {
			throw new BeanDefinitionStoreException("I/O failure during classpath scanning", ex);
		}
		//返回
		return candidates;
	}
}

这个方法就很简单了,系统解析了路径,并找到路径下所有的class文件,那么spring怎么知道哪些是需要加载配置的呢,这时在上面着重让大家记住的includeFilter就起作用了,由于其加入了@Component注解的支持,我们看这个isCandidateComponent方法。

protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {
	for (TypeFilter tf : this.excludeFilters) {
		if (tf.match(metadataReader, getMetadataReaderFactory())) {
			return false;
		}
	}
	for (TypeFilter tf : this.includeFilters) {
		if (tf.match(metadataReader, getMetadataReaderFactory())) {
			return isConditionMatch(metadataReader);
		}
	}
	return false;
}

看了这个方法相信大家就了然了,只有includeFilter为true才会返回true,这儿还有点需要注意的是isConditionMatch,这个处理的是@Conditional系列的注解,用来判定是否满足加载配置的条件。如果不满足则不必加载,会返回false。

来看component-scan的几个属性

  • basePackages:Spring将扫描的基础package名,Spring会扫描该包以及其子孙包下的所有类。

  • useDefaultFilters:默认为true,此时Spring扫描类时发现如果其被标注为 @Component、@Repository、@Service、@Controller则自动实例化为bean并将其添加到上下文中,如果设置为false,即使将其标注为@Component或者其他,Spring都会忽略。

  • includeFilters:指定扫描时需要实例化的类型,我们可以从名字看到这是一个Filter,你可以自己定义该Filter,Spring为我们提供了一套方便的实现,我们可以根据标注、类、包等相关信息决定当扫描到该类时是否需要实例化该类,需要注意的是如果你仅仅想扫描如@Controller不仅要加includeFilters,还需要将useDefaultFilters设置为false

  • excludeFilter:指定扫描到某个类时需要忽略它,实现和上一个Filter一样,区别只是如果Filter匹配,Spring会忽略该类。

这样includeFilters以及excludeFilterF的行为就很清楚了,Spring每扫描一个类,都会经过includeFilters以及excludeFilters,如果某个Filter匹配,就执行相应的操作(实例化或者忽略)。

接着回到doScan方法中,该方法最后会调用registerBeanDefinition(definitionHolder, this.registry)方法,将扫描出来的BeanDefinition注册到到spring的容器中

//将该配置类注入到spring的registry中
registerBeanDefinition(definitionHolder, this.registry);
public class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateComponentProvider {

	protected void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) {
		BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, registry);
	}
}

public abstract class BeanDefinitionReaderUtils {

	public static void registerBeanDefinition(
			BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
			throws BeanDefinitionStoreException {

		// Register bean definition under primary name.
		// 使用beanName做唯一标识注册
		String beanName = definitionHolder.getBeanName();
		registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

		// Register aliases for bean name, if any.
		// 注册所有的别名
		String[] aliases = definitionHolder.getAliases();
		if (aliases != null) {
			for (String alias : aliases) {
				registry.registerAlias(beanName, alias);
			}
		}
	}
}
  • 最终将解析出来的BeanDefinition封装到BeanDefinitionHolder中,由BeanDefinitionReaderUtils的registerBeanDefinition方法将BeanDefinition注册到Spring IOC容器中。
  • 最终调用DefaultListableBeanFactory类的registerBeanDefinition方法将beanDefinition注册到beanDefinitionMap中。

4、处理@Import注解

processImports(configClass, sourceClass, getImports(sourceClass), filter, true);

processImports方法负责对@Import注解进行解析。configClass是配置类,sourceClass又是通过configClass创建的,getImports(sourceClass)从sourceClass获取所有的@Import注解信息

class ConfigurationClassParser {

	private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
			Collection<SourceClass> importCandidates, Predicate<String> exclusionFilter,
			boolean checkForCircularImports) {

		if (importCandidates.isEmpty()) {
			return;
		}

		//循环导入直接报错
		if (checkForCircularImports && isChainedImportOnStack(configClass)) {
			this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));
		}
		else {
			//推入栈
			this.importStack.push(configClass);
			try {
				//循环遍历
				for (SourceClass candidate : importCandidates) {
					//对import的内容进行分类
					// import导入实现ImportSelector接口的类
					if (candidate.isAssignable(ImportSelector.class)) {
						// Candidate class is an ImportSelector -> delegate to it to determine imports
						Class<?> candidateClass = candidate.loadClass();
						// 反射创建这个类的实例对象
						ImportSelector selector = ParserStrategyUtils.instantiateClass(candidateClass, ImportSelector.class,
								this.environment, this.resourceLoader, this.registry);
						//是否有实现相关Aware接口,如果有,这调用相关方法
						Predicate<String> selectorFilter = selector.getExclusionFilter();
						// 延迟加载的ImportSelector
						if (selectorFilter != null) {
							exclusionFilter = exclusionFilter.or(selectorFilter);
						}
						if (selector instanceof DeferredImportSelector) {
							//  延迟加载的ImportSelector先放到List中,延迟加载
							this.deferredImportSelectorHandler.handle(configClass, (DeferredImportSelector) selector);
						}
						else {
							// 普通的ImportSelector ,执行其selectImports方法,获取需要导入的类的全限定类名数组
							String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
							Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames, exclusionFilter);
							// 递归调用
							processImports(configClass, currentSourceClass, importSourceClasses, exclusionFilter, false);
						}
					}
					// 是否为ImportBeanDefinitionRegistrar
					else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
						// Candidate class is an ImportBeanDefinitionRegistrar ->
						// delegate to it to register additional bean definitions
						Class<?> candidateClass = candidate.loadClass();
						ImportBeanDefinitionRegistrar registrar =
								ParserStrategyUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class,
										this.environment, this.resourceLoader, this.registry);
						// 添加到成员变量
						configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
					}
					else {
						// Candidate class not an ImportSelector or ImportBeanDefinitionRegistrar ->
						// process it as an @Configuration class
						// 普通 @Configuration class
						this.importStack.registerImport(
								currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
						// 解析导入的@Configuration class
						processConfigurationClass(candidate.asConfigClass(configClass), exclusionFilter);
					}
				}
			}
			catch (BeanDefinitionStoreException ex) {
				throw ex;
			}
			catch (Throwable ex) {
				throw new BeanDefinitionStoreException(
						"Failed to process import candidates for configuration class [" +
						configClass.getMetadata().getClassName() + "]", ex);
			}
			finally {
				this.importStack.pop();
			}
		}
	}
}

5、处理@ImportResource注解

@ImportResource注解可以导入xml配置文件。

// Process any @Import annotations
// 处理@Import注解
processImports(configClass, sourceClass, getImports(sourceClass), filter, true);

// Process any @ImportResource annotations
// 处理@ImportResource 注解
AnnotationAttributes importResource =
		AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
if (importResource != null) {
	String[] resources = importResource.getStringArray("locations");
	Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
	// 遍历配置的locations,加入到configClass 中的ImportedResource
	for (String resource : resources) {
		String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
		//把配置项提取出来,跟reader一起放入configClass的map中,
		//接下来会在ConfigurationClassPostProcessor类中processConfigBeanDefinitions方法中,解析完,
		//this.reader.loadBeanDefinitions(configClasses)这方法会对@import处理(对ImportBeanDefinitionRegistrars的处理)
		configClass.addImportedResource(resolvedResource, readerClass);
	}
}

6、处理@Bean修饰的方法

// Process individual @Bean methods
// 处理@Bean修饰的方法
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
for (MethodMetadata methodMetadata : beanMethods) {
	//添加到configClass的beanMethods集合中,接下来,会在this.reader.loadBeanDefinitions(configClasses)这方法
	//得到处理
	configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}

7、处理接口定义的方法

// Process default methods on interfaces
// 处理接口定义的方法
processInterfaces(configClass, sourceClass);

8、处理父类

// Process superclass, if any
// 8.如果有父类则递归读取父类
if (sourceClass.getMetadata().hasSuperClass()) {
	String superclass = sourceClass.getMetadata().getSuperClassName();
	if (superclass != null && !superclass.startsWith("java") &&
			!this.knownSuperclasses.containsKey(superclass)) {
		this.knownSuperclasses.put(superclass, configClass);
		// Superclass found, return its annotation metadata and recurse
		return sourceClass.getSuperClass();
	}
}

// No superclass -> processing is complete
// 没有父类直接返回
return null;

参考: https://www.abboke.com/jsh/2019/0628/4154.html

https://www.cnblogs.com/ZhuChangwu/p/11674684.html

https://blog.csdn.net/tuoni123/article/details/79976105

https://www.cnblogs.com/TimeSay/p/10874476.html

https://zhuanlan.zhihu.com/p/83473498

https://www.cnblogs.com/hello-shf/p/10987360.html

https://www.cnblogs.com/duanxz/p/11239291.html

https://www.cnblogs.com/mufeng07/p/12165616.html

https://www.cnblogs.com/mufeng07/p/12172549.html

https://www.cnblogs.com/hetutu-5238/p/12378432.html

标签:configClass,beanFactory,bean,registry,new,解析,IOC,class,Spring5
From: https://blog.51cto.com/u_14014612/5995708

相关文章

  • Spring5 IOC容器解析——后置处理器PostProcessor
    后置处理器PostProcessor其本身也是一种需要注册到容器中的Bean其里面的方法会在特定时机被容器调用实现不改变容器或者Bean核心逻辑的情况下对Bean进行扩展对Bean进行......
  • Spring5 IOC容器解析——Aware接口
    AwareAware是Spring中的一个根接口,继承该接口的子接口有很多,但是该接口没有任何方法,所以大家可以把它理解成一个标记接口: Spring框架中提供了许多实现了Aware接口的......
  • Spring5 IOC容器解析——事件监听机制
    一、事件驱动模型简介事件驱动模型,也即是我们通常说的观察者。基于发布-订阅模式的编程模型。概念定义对象间的一种一对多的依赖关系,当一个对象的状态发生变化时,所有依赖......
  • 数据可视化大屏百度地图GPS轨迹位置感知状态开发实战案例解析(百度地图jsAPI,包含缩放控
    系列文章目录1.​​数据可视化大屏应急管理综合指挥调度系统完整案例详解(PHP-API、Echarts、百度地图)​​2.数据可视化大屏百度地图API开发:停车场分布标注和检索静态版3.......
  • Spring5 IOC容器解析——BeanDefinitionReader
    概述BeanDefinitionReader的作用是读取Spring配置文件中的内容,将其转换为IOC容器内部的数据结构:BeanDefinition。在前面章节关于BeanDefinition的学习中有提到XmlB......
  • Spring5 IOC容器解析——BeanDefinition的注册
    前言在上一篇文章解析BeanDefinition对配置文件解析完成后,获取的beanDefiniton已经可以进行使用了,剩下的唯一工作就是注册了,也就是processBeanDefinition方法中的BeanDefi......
  • Spring IOC官方文档学习笔记(七)之Bean Definition继承
    1.BeanDefinition继承(1)Spring中的bean存在层级关系,我们可以定义子bean来继承或覆盖父bean中的某些属性,从而节省编码,在此处Spring运用到了模板设计模式,如下所示//自定......
  • 爬虫模块——数据解析之bs4模块
    目录模块bs4(beautifulSoup)基本概念基本使用模块bs4(beautifulSoup)基本概念BeautifulSoup是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现......
  • 使用Bind提供域名解析服务
    DNS域名系统,万维网上作为域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串。通过域名,最终得到该域名对应的IP......
  • c# 利用 webbrowser 解析 html
    using(varwb=newWebBrowser()){wb.ScriptErrorsSuppressed=true;wb.Navigate("about:blank");varstartTime=D......