spring源码 之 ConfigurationClassPostProcessor

158 阅读4分钟

ConfigurationClassPostProcessor 是什么

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

可以看到该类继承了 BeanDefinitionRegistryPostProcessor

BeanDefinitionRegistryPostProcessor 是什么,有什么用

public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {

BeanDefinitionRegistryPostProcessor 继承了 BeanFactoryPostProcessor

BeanFactoryPostProcessor 是什么,有什么用

	/**
	 * Modify the application context's internal bean factory after its standard
	 * initialization. All bean definitions will have been loaded, but no beans
	 * will have been instantiated yet. This allows for overriding or adding
	 * properties even to eager-initializing beans.
	 * @param beanFactory the bean factory used by the application context
	 * @throws org.springframework.beans.BeansException in case of errors
	 */
	void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

上面的注释翻译下来大概意思是:可以参与应用上下文bena工厂初始化,所有的bean定义都被加载了,但是没有被实例化,允许我们去修改添加属性,甚至初始化bean(这个不懂,但是感觉一般都是用来修改已有的bean定义或者添加bean定义)

所以 ConfigurationClassPostProcessor 也有这个作用

什么时候执行

org.springframework.context.support.AbstractApplicationContext#refresh

public void refresh() {
    // 。。。 省略代码
    invokeBeanFactoryPostProcessors(beanFactory);
    //。。。 省略代码
    
}
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    // 获取自定义的 beanFactoyrPorcessor 并且 执行
	PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
    //。。。 省略代码
}

先执行 postProcessBeanDefinitionRegistry

沃日 好复杂

1.ConfigurationClassPostProcessor#processConfigBeanDefinitions

public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
		List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
		// 获取所有已经在bean工厂的beandifition 名称
		String[] candidateNames = registry.getBeanDefinitionNames();
		//循环遍历beandifition名称
		for (String beanName : candidateNames) {
		        //从bean工厂中获取beandifition
			BeanDefinition beanDef = registry.getBeanDefinition(beanName);
			//判断这个beandefinition 是否被解析过,如果解析过,会往beandifition加一个标志
			//标志有两种,一种值为full,一种为lite 后面会说到
			if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
					ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
				 // 去掉日志
			}
			//如果没有被解析过,会判断是否需要解析(下面讲)就往 configCandidates 添加
			else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
				configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
			}
		}

		//。。。去掉判空和对 configCandidates 进行排序
	    // 。。。去掉 BeanNameGenerator 和环境的生成
		// Parse each @Configuration class
		// 配置类解析,重要
		ConfigurationClassParser parser = new ConfigurationClassParser(...);

		Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
		Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
		do {
		   //重要,开始解析类
			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(....);
			}
			this.reader.loadBeanDefinitions(configClasses);
			alreadyParsed.addAll(configClasses);
		   //。。。 省略一些不影响主流程的代码,
		}
		while (!candidates.isEmpty());
	     //。。。 省略一些不影响主流程的代码
	}

2.ConfigurationClassUtils.checkConfigurationClassCandidate

public static boolean checkConfigurationClassCandidate(
			BeanDefinition beanDef, MetadataReaderFactory metadataReaderFactory) {
		String className = beanDef.getBeanClassName();
		//todo 这个不懂,为什么有 工厂方法就不解析? 
		if (className == null || beanDef.getFactoryMethodName() != null) {
			return false;
		}
		AnnotationMetadata metadata;
	    // 。。。 去掉获取 metadata 的过程
        // 这个判读的方法 metadata.isAnnotated(Configuration.class.getName())
        //其实就判断是否注释了 @Configuration,如果有这个注释,那么设置参数值为
        // full
		if (isFullConfigurationCandidate(metadata)) {
			beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);
		}
		//这个方法比较长,大概意思就是有没有 @Component @ComponentScan
		//@Import @ImportResource 这几个注解,方法是否有@Bean 这个注解
		//所以可以看出来这几个注解在 ConfigurationClassPostProcessor中都
		//被相应的解析,如果有就设置参数为lite
		else if (isLiteConfigurationCandidate(metadata)) {
			beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);
		}
		else {
			return false;
		}
		//  用来设置order 排序
		Integer order = getOrder(metadata);
		if (order != null) {
			beanDef.setAttribute(ORDER_ATTRIBUTE, order);
		}
		return true;
	}

3.ConfigurationClassParser#parse 重点

public void parse(Set<BeanDefinitionHolder> configCandidates) {
		for (BeanDefinitionHolder holder : configCandidates) {
			BeanDefinition bd = holder.getBeanDefinition();
			try {
				if (bd instanceof AnnotatedBeanDefinition) {
				    // 通过 bean的元信息进行解析
					parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
				}
				//......
			}
		}
            .......
	}

3.1.ConfigurationClassParser#processConfigurationClass

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

protected void processConfigurationClass(ConfigurationClass configClass)  {
   // 检查是否要跳过 跟 @Conditional 有关,没认真看
	if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
		return;
	}
	//....省略无关主流程代码  
	// 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);
}
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass) {
            //处理@Component 
		if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
			// Recursively process any member (nested) classes first
			processMemberClasses(configClass, sourceClass);
		}
		// Process any @PropertySource annotations
		//处理 @PropertySources
		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
				// 这个很重要,解析 @ComponentScans 并且将解析出来的路径进行扫描
				//扫描得到的类,如果有@Compent等注解就注册到bean工厂中
				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
				// 这个是扫描出来的beandifition,进行迭代,防止还有@ComponentScans等注解需要解析
				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), true);

		// Process any @ImportResource annotations
		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);
			}
		}

		// Process individual @Bean methods
		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;
	}

3.1.1 @Import的解析

@Import()里面的value 可以放三种类 1.普通类 2.ImportSelector 3.ImportBeanDefinitionRegistrar 在ConfigurationClassParser#processImprots中解析


	private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
			Collection<SourceClass> importCandidates, boolean checkForCircularImports) {
			//。。。省略无关主流程代码
		else {
			this.importStack.push(configClass);
			try {
				for (SourceClass candidate : importCandidates) {
					if (candidate.isAssignable(ImportSelector.class)) {
						Class<?> candidateClass = candidate.loadClass();
						//如果是ImportSelector 类,实例化
						ImportSelector selector = BeanUtils.instantiateClass(candidateClass, ImportSelector.class);
						ParserStrategyUtils.invokeAwareMethods(
								selector, this.environment, this.resourceLoader, this.registry);
								//如果是 DeferredImportSelector 就先放在
								//deferredImportSelectors中,主要是是延迟加载,后面如果还记得就会说道哪里加载
						if (selector instanceof DeferredImportSelector) {
							this.deferredImportSelectorHandler.handle(
									configClass, (DeferredImportSelector) selector);
						}
						else {
						//如果不是延迟加载的ImportSelectors,就调用 selectImports
						方法,返回需要被bena工厂管理的bean全类名
							String[] importClassNames = selector. selectImports
							(currentSourceClass.getMetadata());
							Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames);
							//防止这些类有标志import,所以进行迭代
							processImports(configClass, currentSourceClass, importSourceClasses, false);
						}
					}
					else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
					// 如果是ImportBeanDefinitionRegistrar 就往 importBeanDefinitionRegistrars ,后面会集中对这个list进行你处理,主要是调用ImportBeanDefinitionRegistrar#registerBeanDefinitions
						Class<?> candidateClass = candidate.loadClass();
						ImportBeanDefinitionRegistrar registrar =
								BeanUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class);
						ParserStrategyUtils.invokeAwareMethods(
								registrar, this.environment, this.resourceLoader, this.registry);
						configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
					}
					else {
					// 这个是普通的类,有两种情况,一种ImportSelector返回的普通类,一种本来就是import的普通类,都会调用 processConfigurationClass方法进行递归处理,可能这些普通类有标志@CompentScans等注解需要解析处理
						// Candidate class not an ImportSelector or ImportBeanDefinitionRegistrar ->
						// process it as an @Configuration class
						this.importStack.registerImport(
								currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
						processConfigurationClass(candidate.asConfigClass(configClass));
					}
				}
			}
			//。。。。。。
		}
	}

ConfigurationClassPostProcessor#postProcessBeanFactory


public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		int factoryId = System.identityHashCode(beanFactory);
		if (this.factoriesPostProcessed.contains(factoryId)) {
			throw new IllegalStateException(
					"postProcessBeanFactory already called on this post-processor against " + beanFactory);
		}
		this.factoriesPostProcessed.add(factoryId);
		if (!this.registriesPostProcessed.contains(factoryId)) {
			// BeanDefinitionRegistryPostProcessor hook apparently not supported...
			// Simply call processConfigurationClasses lazily at this point then.
			processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
		}
       //对 @Configureation 注解进行 cglib 代理
		enhanceConfigurationClasses(beanFactory);
		beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
	}

enhanceConfigurationClasses


public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) {
		Map<String, AbstractBeanDefinition> configBeanDefs = new LinkedHashMap<>();
		for (String beanName : beanFactory.getBeanDefinitionNames()) {
			BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName);
            //如果是全注解 也就是加了 @Configuration 注解的配置类
			if (ConfigurationClassUtils.isFullConfigurationClass(beanDef)) {
				if (!(beanDef instanceof AbstractBeanDefinition)) {
//...........
				configBeanDefs.put(beanName, (AbstractBeanDefinition) beanDef);
			}
		}
//对全注解类生成代理类
		ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer();
		for (Map.Entry<String, AbstractBeanDefinition> entry : configBeanDefs.entrySet()) {
//....
//生成代理类
					Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);
					//.....
						beanDef.setBeanClass(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));
		enhancer.setCallbackFilter(CALLBACK_FILTER);
		enhancer.setCallbackTypes(CALLBACK_FILTER.getCallbackTypes());
		return enhancer;
	}

所以 @Bean 最后会执行的方法是 BeanMethodInterceptor#intercept 和 BeanFactoryAwareMethodInterceptor#intercept。在getBean的时候会判断 factoryMethodName 是否为空,如果不为空,就会走,工厂方法获取bean。

......未完待续 还有好多