spring-boot bean初始化源码分析(一)

测试环境:

 spring-boot-2.0.1.RELEASE

 spring 5.0.5.RELEASE

/**
 * spring容器启动时,主要操作都在这个方法中实现
 * AbstractApplicationContext
 */
public void refresh() throws BeansException, IllegalStateException {
    ......
    // Invoke factory processors registered as beans in the context.
    // 执行BeanFactoryPostProcessors接口模板方法
    invokeBeanFactoryPostProcessors(beanFactory);
    ......
}

/**
 * AbstractApplicationContext
 */
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
	// 执行BeanFactoryPostProcessors接口模板方法
	PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
    ......
}

/**
 * 此方法对实现了BeanFactoryPostProcessors接口的类进行不同的处理
 * PostProcessorRegistrationDelegate
 */
public static void invokeBeanFactoryPostProcessors(
	ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
	......
	// 这个方法中还有其它的一些处理,今天先看一下下面实现了BeanDefinitionRegistryPostProcessor和PriorityOrdered的接口
	// beanFactory中有一个实现类ConfigurationClassPostProcessor,这个类就是用来将Bean初始化为BeanDefinition的
	// ConfigurationClassPostProcessor是什么时候注入的呢?
	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);
	// 调用ConfigurationClassPostProcessor
	invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
	currentRegistryProcessors.clear();
	......
}

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

	for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
		// 调用ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry
		postProcessor.postProcessBeanDefinitionRegistry(registry);
	}
}

/**
 * 此方法基于springboot启动类的配置进行扫描
 * ConfigurationClassPostProcessor
 */
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
	List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
	String[] candidateNames = registry.getBeanDefinitionNames();

	for (String beanName : candidateNames) {
		BeanDefinition beanDef = registry.getBeanDefinition(beanName);
		if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
				ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
			if (logger.isDebugEnabled()) {
				logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
			}
		}
		else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
			configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
		}
	}

	// @Configuration的解析类
	ConfigurationClassParser parser = new ConfigurationClassParser(
			this.metadataReaderFactory, this.problemReporter, this.environment,
			this.resourceLoader, this.componentScanBeanNameGenerator, registry);

	Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
	Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
	do {
		// 对添加了注解@Configuration的配置类进行扫描
		// 基于springboot启动类的BeanDefinitionHolder进行解析
		parser.parse(candidates);
		parser.validate();

		Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
		configClasses.removeAll(alreadyParsed);

		// Read the model and create bean definitions based on its content
		if (this.reader == null) {
			this.reader = new ConfigurationClassBeanDefinitionReader(
					registry, this.sourceExtractor, this.resourceLoader, this.environment,
					this.importBeanNameGenerator, parser.getImportRegistry());
		}
		// 对其它的BeanDefinition(例如BeanMethod,ImportedResources,BeanDefinitionRegistrars)添加的beanFactory中
		this.reader.loadBeanDefinitions(configClasses);
	}
	while (!candidates.isEmpty());
}


/**
 * 对自定义配置类和META-INF/spring-autoconfigure-metadata.properties中配置类进行解析
 * ConfigurationClassPostProcessor
 */
public void parse(Set<BeanDefinitionHolder> configCandidates) {
	this.deferredImportSelectors = new LinkedList<>();

	for (BeanDefinitionHolder holder : configCandidates) {
		BeanDefinition bd = holder.getBeanDefinition();
		try {
			// 对不同的BeanDefinition进行解析
			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);
		}
	}
	// 对DeferredImportSelectors接口实现类进行处理,后面会讲到
	processDeferredImportSelectors();
}

 


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

/**
 * 此方法会解析类的父类进行递归的解析,并添加到ConfigurationClassParser的configurationClasses集合中
 * ConfigurationClassPostProcessor
 */
protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {
	if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
		return;
	}

	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);
	do {
		sourceClass = doProcessConfigurationClass(configClass, sourceClass);
	}
	while (sourceClass != null);

	this.configurationClasses.put(configClass, configClass);
}

 


/**
 * 此方法定义了配置类的解析顺序:
 *  1.解析内部嵌套的Bean,添加到parser.configurationClasses
 *  2.解析@PropertySource,添加到parser.propertySourceNames
 *  3.解析@ComponentScan,将解析类注入到beanFactory中,并添加到parser.configurationClasses,会递归执行
 *  4.解析 @Import,获取要注入的类
 *     4.1 注入类实现了DeferredImportSelector接口,添加到parser.deferredImportSelectors
 *     4.2 注入类实现了ImportBeanDefinitionRegistrar接口,添加到configClass.importBeanDefinitionRegistrars
 *     4.3 其它,添加到parser.configurationClasses
 *  5.解析@ImportResource,添加到configClass.importedResources
 *  6.解析类中添加了@Bean的方法类,添加到configClass.beanMethods
 *  7.解析类实现的接口中添加@Bean的方法类,添加到configClass.beanMethods
 *  8.解析父类
 * ConfigurationClassPostProcessor
 */
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)
		throws IOException {

	// 1.递归解析成员内部类
	processMemberClasses(configClass, sourceClass);

	// 2.解析@PropertySource,添加到parser.propertySourceNames
	for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
			sourceClass.getMetadata(), PropertySources.class,
			org.springframework.context.annotation.PropertySource.class)) {
		if (this.environment instanceof ConfigurableEnvironment) {
			processPropertySource(propertySource);
		}
		else {
			logger.warn("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
					"]. Reason: Environment must implement ConfigurableEnvironment");
		}
	}

	//  3.解析@ComponentScan,将解析类注入到beanFactory中,并添加到parser.configurationClasses,会递归执行
	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) {
				if (ConfigurationClassUtils.checkConfigurationClassCandidate(
						holder.getBeanDefinition(), this.metadataReaderFactory)) {
					// 会递归执行
					parse(holder.getBeanDefinition().getBeanClassName(), holder.getBeanName());
				}
			}
		}
	}

	// 4.解析 @Import,获取要注入的类
	//     4.1 注入类实现了DeferredImportSelector接口,添加到parser.deferredImportSelectors
	//     4.2 注入类实现了ImportBeanDefinitionRegistrar接口,添加到configClass.importBeanDefinitionRegistrars
	//     4.3 其它,添加到parser.configurationClasses
	processImports(configClass, sourceClass, getImports(sourceClass), true);

	// 5.解析@ImportResource,添加到configClass.importedResources
	AnnotationAttributes importResource =
			AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
	if (importResource != null) {
		String[] resources = importResource.getStringArray("locations");
		Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
		for (String resource : resources) {
			String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
			configClass.addImportedResource(resolvedResource, readerClass);
		}
	}

	// 6.解析类中添加了@Bean的方法类,添加到configClass.beanMethods
	Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
	for (MethodMetadata methodMetadata : beanMethods) {
		configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
	}

	// 解析类实现的接口中添加@Bean的方法类,添加到configClass.beanMethods
	processInterfaces(configClass, sourceClass);

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


/**
 * 解析DeferredImportSelector
 * ConfigurationClassPostProcessor
 */
private void processDeferredImportSelectors() {
	// 上面说到parser.deferredImportSelectors是由@Import注解添加的
	// 我们知道springboot启动类上都会添加@SpringBootApplication注解,这是一个组合注解,看一下这个注解里面是否有@Import
	// 在@AutoConfigurationPackage上面有@Import(AutoConfigurationPackages.Registrar.class)
	// 在@EnableAutoConfiguration上面有@Import(AutoConfigurationImportSelector.class),该注解注入了AutoConfigurationImportSelector类
	// AutoConfigurationImportSelector实现了DeferredImportSelectors接口,下面我们就来分析一下这个类的作用
	List<DeferredImportSelectorHolder> deferredImports = this.deferredImportSelectors;
	this.deferredImportSelectors = null;
	if (deferredImports == null) {
		return;
	}

	deferredImports.sort(DEFERRED_IMPORT_COMPARATOR);
	Map<Object, DeferredImportSelectorGrouping> groupings = new LinkedHashMap<>();
	Map<AnnotationMetadata, ConfigurationClass> configurationClasses = new HashMap<>();
	for (DeferredImportSelectorHolder deferredImport : deferredImports) {
		Class<? extends Group> group = deferredImport.getImportSelector().getImportGroup();
		DeferredImportSelectorGrouping grouping = groupings.computeIfAbsent(
				(group == null ? deferredImport : group),
				(key) -> new DeferredImportSelectorGrouping(createGroup(group)));
		grouping.add(deferredImport);
		configurationClasses.put(deferredImport.getConfigurationClass().getMetadata(),
				deferredImport.getConfigurationClass());
	}
	for (DeferredImportSelectorGrouping grouping : groupings.values()) {
		// 获取"META-INF/spring-autoconfigure-metadata.properties"文件中class全限定名
		grouping.getImports().forEach((entry) -> {
			ConfigurationClass configurationClass = configurationClasses.get(
					entry.getMetadata());
			try {
				// 走@Import解析逻辑
				processImports(configurationClass, asSourceClass(configurationClass),
						asSourceClasses(entry.getImportClassName()), false);
			}
			catch (BeanDefinitionStoreException ex) {
				throw ex;
			}
			catch (Throwable ex) {
				throw new BeanDefinitionStoreException(
						"Failed to process import candidates for configuration class [" +
								configurationClass.getMetadata().getClassName() + "]", ex);
			}
		});
	}
}


/**
 * AutoConfigurationImportSelector
 */
public String[] selectImports(AnnotationMetadata annotationMetadata) {
	if (!isEnabled(annotationMetadata)) {
		return NO_IMPORTS;
	}
	// 加载classpath下"META-INF/spring-autoconfigure-metadata.properties"文件
	AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
			.loadMetadata(this.beanClassLoader);
	AnnotationAttributes attributes = getAttributes(annotationMetadata);
	// 获取properties文件中class全限定名
	List<String> configurations = getCandidateConfigurations(annotationMetadata,
			attributes);
	configurations = removeDuplicates(configurations);
	Set<String> exclusions = getExclusions(annotationMetadata, attributes);
	checkExcludedClasses(configurations, exclusions);
	configurations.removeAll(exclusions);
	configurations = filter(configurations, autoConfigurationMetadata);
	fireAutoConfigurationImportEvents(configurations, exclusions);
	return StringUtils.toStringArray(configurations);
}

final class AutoConfigurationMetadataLoader {

	protected static final String PATH = "META-INF/"
			+ "spring-autoconfigure-metadata.properties";

	private AutoConfigurationMetadataLoader() {
	}

	public static AutoConfigurationMetadata loadMetadata(ClassLoader classLoader) {
		return loadMetadata(classLoader, PATH);
	}

	/**
	 * 加载classpath下"META-INF/spring-autoconfigure-metadata.properties"文件
	 */
	static AutoConfigurationMetadata loadMetadata(ClassLoader classLoader, String path) {
		try {
			Enumeration<URL> urls = (classLoader != null ? classLoader.getResources(path)
					: ClassLoader.getSystemResources(path));
			Properties properties = new Properties();
			while (urls.hasMoreElements()) {
				properties.putAll(PropertiesLoaderUtils
						.loadProperties(new UrlResource(urls.nextElement())));
			}
			return loadMetadata(properties);
		}
		catch (IOException ex) {
			throw new IllegalArgumentException(
					"Unable to load @ConditionalOnClass location [" + path + "]", ex);
		}
	}
}

Spring解析配置类流程

 

再回过头去看一下processConfigBeanDefinitions方法中的this.reader.loadBeanDefinitions(configClasses),添加了@Component注解的配置类在解析@ComponentScan时就已经注入beanFactory中了,其它的(例如BeanMethod,ImportedResources,BeanDefinitionRegistrars)也会在这个方法中注入beanFactory中,此时配置类都已经注入到beanFactory中了,下一篇我们会继续讲spring容器是如何对beanFactory中的BeanDefinition对象进行实例化的。

参考博客:

https://blog.csdn.net/qq_27529917/article/details/79329809

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值