Spring源码解析之ConfigurationClassPostProcessor的processConfigBeanDefinitions过程

        ConfigurationClassPostProcessor实现BeanDefinitionRegistryPostProcessor,是spring内置的后置处理器,在bean的加载初始化过程中处理bean

       ConfigurationClassPostProcessor.processConfigBeanDefinitions处理配置类

       1、遍历所有的已注册的BeanDefinition,校验是否为配置候选类,判断条件是否添加如下注解

       @Configuration,添加该注解的BeanDefinition,添加到该处理器的处理列表中,设置其属性configurationClass为full,后续会判断属性为full的配置类进行cglib增强,原始对象替换为代理对象,调用标注的@Bean 的方法会先从singletonObjects中获取

        @Import、@Component、@ImportResource、@ComponentScan、@Bean;添加这些注解的类添加到该处理器的处理列表中,设置其属性configurationClass为lite,后续不会对该类进行cglib增强

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

                //checkConfigurationClassCandidate
                //校验是否包含了@Configuration注解
                if (isFullConfigurationCandidate(metadata)) {
			beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);
		}
                //校验是否包含了@Component、@Import、@ImportResource、@ComponentScan、@Bean
		else if (isLiteConfigurationCandidate(metadata)) {
			beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);
		}
		else {
			return false;
		}

		// It's a full or lite configuration candidate... Let's determine the order value, if any.
		Integer order = getOrder(metadata);
		if (order != null) {
			beanDef.setAttribute(ORDER_ATTRIBUTE, order);
		}

		return true;

2、创建ConfigurationClassParser解析配置候选类列表

      将配置类封装成SourceClass处理配置类ConfigurationClassParser.doProcessConfigurationClass

      2.1处理@PropertyResource注解,添加到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");
    }
}

     2.2 处理@ComponentScan

      ComponentScanAnnotationParser解析@ComponentScan注解,调用ClassPathBeanDefinitionScanner扫描注解指定的包,scanCandidateComponents,扫描本身包含或继承自@Component注解的类注册到beanDefinitionMap中,递归调用doProcessConfigurationClass,处理新注册的beanDefinition中包含@PropertyResource、@ComponentScan、@Import、@Bean注解的类

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());
			}
		}
	}
}
//ClassPathBeanDefinitionScanner
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
	Assert.notEmpty(basePackages, "At least one base package must be specified");
	Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
	for (String basePackage : basePackages) {
		//扫描包下的所有.class文件,获取包含有@Component注解的类
		Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
		for (BeanDefinition candidate : candidates) {
			ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
			candidate.setScope(scopeMetadata.getScopeName());
			String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
			if (candidate instanceof AbstractBeanDefinition) {
				postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
			}
			if (candidate instanceof AnnotatedBeanDefinition) {
				AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
			}
			if (checkCandidate(beanName, candidate)) {
				BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
				definitionHolder =
						AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
				beanDefinitions.add(definitionHolder);
								//注册到beanDefinition
				registerBeanDefinition(definitionHolder, this.registry);
			}
		}
	}
	return beanDefinitions;
}

   2.3 处理@Import注解

      导入的是 ImportSelector ,调用selectImports方法获取需要导入的类的全路径名称,加载导入的类,并注册到beanDefinition中,递归调用判断导入的类中是为ImportSelector实例

     导入的类是ImportBeanDefinitionRegistrar,ClassConfig中添加ImportBeanDefinitionRegistrar实例

     导入的类是普通类,则作为@Configuration配置类进行校验处理并注册到beanDefinitionMap 中

//处理@Import注解
private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
		Collection<SourceClass> importCandidates, 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 导入的是 ImportSelector 
				if (candidate.isAssignable(ImportSelector.class)) {
					// Candidate class is an ImportSelector -> delegate to it to determine imports
					Class<?> candidateClass = candidate.loadClass();
					//实例化ImportSelector
					ImportSelector selector = BeanUtils.instantiateClass(candidateClass, ImportSelector.class);
					//激活Aware方法判断是否需要进行beanName、beanClassLoader、beanFactory注入
					ParserStrategyUtils.invokeAwareMethods(
							selector, this.environment, this.resourceLoader, this.registry);
					if (this.deferredImportSelectors != null && selector instanceof DeferredImportSelector) {
						this.deferredImportSelectors.add(
								new DeferredImportSelectorHolder(configClass, (DeferredImportSelector) selector));
					}
					else {
						//调用selectImports方法获取需要导入的类的全路径名称
						String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
						//加载导入的类,并注册到beanDefinition中
						Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames);
						//递归调用判断导入的类中是为ImportSelector实例
						processImports(configClass, currentSourceClass, importSourceClasses, 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 =
							BeanUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class);
					//激活Aware方法判断是否需要进行beanName、beanClassLoader、beanFactory注入
					ParserStrategyUtils.invokeAwareMethods(
							registrar, this.environment, this.resourceLoader, this.registry);
					//ClassConfig中添加ImportBeanDefinitionRegistrar实例
					configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
				}
				else {
					// Candidate class not an ImportSelector or ImportBeanDefinitionRegistrar ->
					// process it as an @Configuration class
					this.importStack.registerImport(
							currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
					//导入的类是普通类,则作为@Configuration配置类进行校验处理并注册到beanDefinitionMap 中
					processConfigurationClass(candidate.asConfigClass(configClass));
				}
			}
		}
		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();
		}
	}
}

2.4 处理@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);
	}
}

2.5 处理@Bean

       检索添加@Bean的方法,添加到ConfigClass中的beanMethods的set集合中

Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
for (MethodMetadata methodMetadata : beanMethods) {
	configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}

3、ConfigurationClassBeanDefinitionReader.loadBeanDefinitions

加载解析后封装到配置类ConfigurationClass属性中的beanDefinition

private void loadBeanDefinitionsForConfigurationClass(
		ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {

	if (trackedConditionEvaluator.shouldSkip(configClass)) {
		String beanName = configClass.getBeanName();
		if (StringUtils.hasLength(beanName) && this.registry.containsBeanDefinition(beanName)) {
			this.registry.removeBeanDefinition(beanName);
		}
		this.importRegistry.removeImportingClass(configClass.getMetadata().getClassName());
		return;
	}

	//configurationClass本身是通过@Import注册的,将自身注册到beanDefinition中
	if (configClass.isImported()) {
		registerBeanDefinitionForImportedConfigurationClass(configClass);
	}
	//注册@Bean方法到beanDefinition
	//注册的beanDefinition的key为方法名,值为ConfigurationClassBeanDefinition
	//beanDef.setFactoryBeanName(configClass.getBeanName());
	//beanDef.setUniqueFactoryMethodName(methodName);
	for (BeanMethod beanMethod : configClass.getBeanMethods()) {
		loadBeanDefinitionsForBeanMethod(beanMethod);
	}

	//注册通过@ImportResource注解导入的,通过XmlBeanDefinitionReader.loadBeanDefinitions加载解析xml配置文件
	loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
	//调用ImportBeanDefinitionRegistrar的registerBeanDefinitions完成注册到beanDefinition
	loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
}

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值