Spring ConfigurationClassPostProcessor

ConfigurationClassPostProcessor

ConfigurationClassPostProcessor继承BeanDefinitionRegistryPostProcessor接口,刷新IOC容器时调用postProcessBeanDefinitionRegistry方法实现注解的解析。order=Integer.MAX_VALUE
继承BeanFactoryPostProcessor实现postProcessBeanFactory,完成对配置类的cglib代理和添加一个ImportAwareBeanPostProcessor(1.在实例化完成后配置属性时对配置类添加beanFactory感知;2.在初始化时对实现了ImportAware接口的bean配置importingClass)

具体流程

processConfigBeanDefinitions
  1. 获得所有BeanNames
  2. 添加所有配置类到候选集合(full+lite)
  3. 创建解析器来解析ConfigurationClass
  4. 解析+验证(Configuration类不为final,@Bean修饰方法可被继承)
  5. 加载解析的ConfigurationClass
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
	List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
	// 获得容器中所有beanNames
	String[] candidateNames = registry.getBeanDefinitionNames();

	for (String beanName : candidateNames) {
		BeanDefinition beanDef = registry.getBeanDefinition(beanName);
		if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
			···日志打印beanDef已被定义为ConfigurationClass
		}
		// 判断是否为配置类
		else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
			configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
		}
	}

	// 无候选直接返回
	if (configCandidates.isEmpty()) {
		return;
	}

	// 排序
	configCandidates.sort((bd1, bd2) -> {
		int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
		int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
		return Integer.compare(i1, i2);
	});

	// 发现自定义beanName生成器
	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;
			}
		}
	}

	if (this.environment == null) {
		this.environment = new StandardEnvironment();
	}

	// 创建解析器来解析ConfigurationClass
	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 {
		// 核心1
		parser.parse(candidates);
		parser.validate();
		// 获得所有ConfigurationClass排除已被解析的
		Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
		configClasses.removeAll(alreadyParsed);

		// 创建读取器来处理ConfigurationClass
		if (this.reader == null) {
			this.reader = new ConfigurationClassBeanDefinitionReader(
					registry, this.sourceExtractor, this.resourceLoader, this.environment,
					this.importBeanNameGenerator, parser.getImportRegistry());
		}
		// 核心2
		this.reader.loadBeanDefinitions(configClasses);
		alreadyParsed.addAll(configClasses);

		candidates.clear();
		// 如果在加载过程创建了新的bd,确保新的bd被解析
		if (registry.getBeanDefinitionCount() > candidateNames.length) {
			String[] newCandidateNames = registry.getBeanDefinitionNames();
			Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
			Set<String> alreadyParsedClasses = new HashSet<>();
			for (ConfigurationClass configurationClass : alreadyParsed) {
				alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
			}
			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());

	// 将ImportRegistry注册为bean以支持importware
	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();
	}
}
1. ConfigurationClassParser的parse方法
public void parse(Set<BeanDefinitionHolder> configCandidates) {
	for (BeanDefinitionHolder holder : configCandidates) {
		BeanDefinition bd = holder.getBeanDefinition();
		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());
			}
		}
	    ···异常
	}
	// 处理需要延迟处理的ImportSelector,在所有配置加载完成后解析
	this.deferredImportSelectorHandler.process();
}
// 注解BeanDefinition解析,创建ConfigurationClass
protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException {
	processConfigurationClass(new ConfigurationClass(metadata, beanName), DEFAULT_EXCLUSION_FILTER);
}
1.1 processConfigurationClass
  1. 判断是否跳过解析 @Conditional是否存在
  2. 判断当前ConfigurationClass已存在则判断是否有@Import导入,有则合并,否则移除
  3. 调用doProcessConfigurationClass循环处理直至configClass父类未null或已被处理
protected void processConfigurationClass(ConfigurationClass configClass, Predicate<String> filter) throws IOException {
	// 判断是否跳过解析 @Conditional是否存在
	if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
		return;
	}

	ConfigurationClass existingClass = this.configurationClasses.get(configClass);
	// 如果当前ConfigurationClass已存在则判断是否有@Import导入,有则合并,否则移除
	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);
		}
	}

	// 调用doProcessConfigurationClass循环处理直至configClass父类未null或已被处理
	SourceClass sourceClass = asSourceClass(configClass, filter);
	do {
		sourceClass = doProcessConfigurationClass(configClass, sourceClass, filter);
	}
	while (sourceClass != null);

	this.configurationClasses.put(configClass, configClass);
}
1.2 doProcessConfigurationClass
  1. 存在@Component注解则判断是否有嵌套的配置类,存在则递归调用processConfigurationClass处理
  2. 处理@PropertySource,加入environment中,IOC容器的environment必须为ConfigurableEnvironment
  3. 处理@ComponentScan注解,扫描包位置下的@Component修饰的类(通过includeFilters排除),对生成的bd递归调用prase方法
  4. 处理@Import注解,分别处理ImportSelector、ImportBeanDefinitionRegistrar及其他配置类,递归processConfigurationClass带入ImportBy处理配置类
  5. 处理@ImportResource注解,记录到ConfigurationClass的importedResources中
  6. 处理@Bean注解,记录到ConfigurationClass的beanMethods中
protected final SourceClass doProcessConfigurationClass(
			ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter)
			throws IOException {

	if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
		// 递归调用processConfigurationClass处理嵌套配置类
		processMemberClasses(configClass, sourceClass, filter);
	}

	// 处理@PropertySource注解
	for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
			sourceClass.getMetadata(), PropertySources.class,
			org.springframework.context.annotation.PropertySource.class)) {
		if (this.environment instanceof ConfigurableEnvironment) {
			processPropertySource(propertySource);
		}
		···日志
	}

	// 处理@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) {
			// 扫描包位置下的@Component修饰的类(通过includeFilters排除)
			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();
				}
				// 对生成的bd递归调用prase方法
				if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
					parse(bdCand.getBeanClassName(), holder.getBeanName());
				}
			}
		}
	}

	// 分别处理ImportSelector、ImportBeanDefinitionRegistrar及其他配置类
	processImports(configClass, sourceClass, getImports(sourceClass), filter, true);

	// 处理@ImportResource注解,记录到ConfigurationClass中
	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);
		}
	}

	// 处理@Bean注解定义的方法
	Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
	for (MethodMetadata methodMetadata : beanMethods) {
		configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
	}

	// 处理接口上的缺省方法
	processInterfaces(configClass, sourceClass);

	// 存在父类,处理
	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();
		}
	}

	// 无父类,处理完成
	return null;
}
2. loadBeanDefinitions
public void loadBeanDefinitions(Set<ConfigurationClass> configurationModel) {
	TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator();
	// 遍历加载ConfigurationClass到BeanFactory
	for (ConfigurationClass configClass : configurationModel) {
		loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);
	}
}
2.1 loadBeanDefinitionsForConfigurationClass

根据不同ConfigurationClass执行不同的装载方法

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;
	}
	// 如果是Import则加载为AnnotatedGenericBeanDefinition
	if (configClass.isImported()) {
		registerBeanDefinitionForImportedConfigurationClass(configClass);
	}
	// @Bean方法加载,默认使用方法名作为Bean名,通过设置FactoryBeanName,FactoryMethodName来完成bd的初始化
	for (BeanMethod beanMethod : configClass.getBeanMethods()) {
		loadBeanDefinitionsForBeanMethod(beanMethod);
	}
	// @ImportResource加载,读取资源中的BeanDifinition
	loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
	// ImportBeanDefinitionRegistrar处理,调用registerBeanDefinitions注册BeanDifinition
	loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
}
enhanceConfigurationClasses增强配置类

遍历找出所有@Configuration修饰的类,使用cglib动态代理增强配置类对象

public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) {
	Map<String, AbstractBeanDefinition> configBeanDefs = new LinkedHashMap<>();
	for (String beanName : beanFactory.getBeanDefinitionNames()) {
		BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName);
		Object configClassAttr = beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE);
		MethodMetadata methodMetadata = null;
		···省略代码
		// 如果当前bean为@Configuration修饰的类加入configBeanDefs中
		if (ConfigurationClassUtils.CONFIGURATION_CLASS_FULL.equals(configClassAttr)) {
			···异常日志
			configBeanDefs.put(beanName, (AbstractBeanDefinition) beanDef);
		}
	}
	// 为空不增强
	if (configBeanDefs.isEmpty()) {		
		return;
	}

	ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer();
	for (Map.Entry<String, AbstractBeanDefinition> entry : configBeanDefs.entrySet()) {
		AbstractBeanDefinition beanDef = entry.getValue();
		// If a @Configuration class gets proxied, always proxy the target class
		beanDef.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);
		// Set enhanced subclass of the user-specified bean class
		Class<?> configClass = beanDef.getBeanClass();
		// 代理configClass
		Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);
		// 如果不等表示代理成功,修改bd对应的beanClass
		if (configClass != enhancedClass) {
			··· 日志
			beanDef.setBeanClass(enhancedClass);
		}
	}
}
enhance增强
  1. 代理类继承@Configuration修饰的类并且实现EnhancedConfiguration接口感知beanFactory
public Class<?> enhance(Class<?> configClass, @Nullable ClassLoader classLoader) {
	// 已被代理直接返回
	if (EnhancedConfiguration.class.isAssignableFrom(configClass)) {
		···日志
		return configClass;
	}
	Class<?> enhancedClass = createClass(newEnhancer(configClass, classLoader));
	···日志
	return enhancedClass;
}
private Enhancer newEnhancer(Class<?> configSuperClass, @Nullable ClassLoader classLoader) {
	Enhancer enhancer = new Enhancer();
	// 设置被代理类
	enhancer.setSuperclass(configSuperClass);
	enhancer.setInterfaces(new Class<?>[] {EnhancedConfiguration.class});
	enhancer.setUseFactory(false);
	enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
	enhancer.setStrategy(new BeanFactoryAwareGeneratorStrategy(classLoader));
	// 设置拦截器、过滤器及其类型    默认拦截器:BeanMethodInterceptor   BeanFactoryAwareMethodInterceptor  NoOp.INSTANCE
	enhancer.setCallbackFilter(CALLBACK_FILTER);
	enhancer.setCallbackTypes(CALLBACK_FILTER.getCallbackTypes());
	return enhancer;
}
1.1 BeanFactoryAwareMethodInterceptor

当调用setBeanFactory方法时进行拦截

public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
	// 找到代理的$$beanFactory字段设置值
	Field field = ReflectionUtils.findField(obj.getClass(), BEAN_FACTORY_FIELD);
	
	field.set(obj, args[0]);

	// 如果父类实现了BeanFactoryAware则调用其setBeanFactory设置
	if (BeanFactoryAware.class.isAssignableFrom(ClassUtils.getUserClass(obj.getClass().getSuperclass()))) {
		return proxy.invokeSuper(obj, args);
	}
	return null;
}
1.2 BeanMethodInterceptor

判断方法含有注解@Bean

public Object intercept(Object enhancedConfigInstance, Method beanMethod, Object[] beanMethodArgs,
					MethodProxy cglibMethodProxy) throws Throwable {

	ConfigurableBeanFactory beanFactory = getBeanFactory(enhancedConfigInstance);
	String beanName = BeanAnnotationHelper.determineBeanNameFor(beanMethod);

	// 是否存在@Scope代理
	if (BeanAnnotationHelper.isScopedProxy(beanMethod)) {
		String scopedBeanName = ScopedProxyCreator.getTargetBeanName(beanName);
		if (beanFactory.isCurrentlyInCreation(scopedBeanName)) {
			beanName = scopedBeanName;
		}
	}

	// 为了处理bean间方法引用的情况,显式地检查容器中是否有已缓存的实例。

	// FactoryBean处理
	if (factoryContainsBean(beanFactory, BeanFactory.FACTORY_BEAN_PREFIX + beanName) &&
			factoryContainsBean(beanFactory, beanName)) {
		Object factoryBean = beanFactory.getBean(BeanFactory.FACTORY_BEAN_PREFIX + beanName);
		if (factoryBean instanceof ScopedProxyFactoryBean) {
			// Scoped proxy factory beans are a special case and should not be further proxied
		}
		else {
			// 增强
			return enhanceFactoryBean(factoryBean, beanMethod.getReturnType(), beanFactory, beanName);
		}
	}
	// 拦截的方法与当前记录的方法一致
	if (isCurrentlyInvokedFactoryMethod(beanMethod)) {
		···日志
		// 调用父类实际方法,创建bean实例
		return cglibMethodProxy.invokeSuper(enhancedConfigInstance, beanMethodArgs);
	}
	// 不一致表示@Bean方法内调用了其他方法获得实例,则直接从beanFactory获取
	return resolveBeanReference(beanMethod, beanMethodArgs, beanFactory, beanName);
}

总结

  1. 解析时@ComponentScan扫描的组件会直接加入BeanFactory的beanDifinitionMap中,其余需等待读取器加载到beanDifinitionMap中
  2. deferredImportSelector是在所有配置类解析完成后再处理
  3. @Bean的加载是通过设置FactoryBeanName,FactoryMethodName来完成
  4. 解析时通过ConditionEvaluator判断是否需要跳过当前类的解析(@Conditional),加载时通过TrackedConditionEvaluator判断,引入当前类的配置类只要有一个允许解析则通过ConditionEvaluator传入Bean阶段来判断是否需要解析。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值