SpringBoot配置类解析-ConfigurationClassPostProcessor后置处理器

在使用springboot工程的时候,如果需要用到配置类我们会这样做。

@Configuration
public class MyConfiguration{
   @Bean 
   public Car car() { 
       Car car = new Car(); 
       ...
       return car; 
   }
}

那么它是怎么注册到spring中让我们使用的呢。

在启动方法refresh中有一个方法: refresh解析

//调用在上下文中注册为 bean 的工厂处理器
invokeBeanFactoryPostProcessors(beanFactory);

该方法会遍历BeanDefinitionRegistryPostProcessor的实现类然后执行postProcessBeanDefinitionRegistry方法。其中有一个实现类为ConfigurationClassPostProcessor。该类主要就是用来解析@Configuration。

ConfigurationClassPostProcessor

  • ConfigurationClassPostProcessor是一个BeanFactory的后置处理器,因此它的主要功能是参与BeanFactory的建造,在这个类中,会解析加了@Configuration的配置类,还会解析@ComponentScan、@ComponentScans注解扫描的包,以及解析@Import等注解。
  • ConfigurationClassPostProcessor主要重写了BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法和BeanFactoryPostProcessor的postProcessBeanFactory方法。

看下它的类图

SpringBoot配置类解析-ConfigurationClassPostProcessor后置处理器_第1张图片

会先执行postProcessBeanDefinitionRegistry方法然后再执行postProcessBeanFactory方法

postProcessBeanDefinitionRegistry

  • 这里的BeanDefinitionRegistry是子类DefaultListableBeanFactory主要就是存放Bean要注册的信息
  • 判断是否在registriesPostProcessed集合或者在factoriesPostProcessed集合中如果存在就说明已经处理过了
  • 执行processConfigBeanDefinitions方法(重要)

点开注解我们可以发现@SpringBootApplication->@SpringBootConfiguration->@Configuration

所以@SpringBootApplication也算是一个@Configuration

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

processConfigBeanDefinitions

  • 遍历BeanDefinitionNames,判断是否是配置类(下面说明什么是配置类)
  • 排序
  • 获取beanName生成器
  • 解析每个 @Configuration 类
	public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
		List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
		String[] candidateNames = registry.getBeanDefinitionNames();

		for (String beanName : candidateNames) {
			BeanDefinition beanDef = registry.getBeanDefinition(beanName);
			//如果有full或者lite标识就是已经被处理过的
			if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
					ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
				if (logger.isDebugEnabled()) {
					logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
				}
			}
			// checkConfigurationClassCandidate()会判断一个是否是一个配置类,并为BeanDefinition设置属性为lite或者full。
            // 在这儿为BeanDefinition设置lite和full属性值是为了后面在使用
            // 如果加了@Configuration,那么对应的BeanDefinition为full;
            // 如果加了@Bean,@Component,@ComponentScan,@Import,@ImportResource这些注解,则为lite。
            // lite和full均表示这个BeanDefinition对应的类是一个配置类
			else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
				configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
			}
		}

		// 如果没有找到 @Configuration 类,则立即返回
		if (configCandidates.isEmpty()) {
			return;
		}

		// 按先前确定的@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
		SingletonBeanRegistry sbr = null;
		if (registry instanceof SingletonBeanRegistry) {
			sbr = (SingletonBeanRegistry) registry;
			if (!this.localBeanNameGeneratorSet) {
			    //beanName的生成器,因为后面会扫描出所有加入到spring容器中calss类,然后把这些class解析成BeanDefinition类,
			    //此时需要利用BeanNameGenerator为这些BeanDefinition生成beanName
				BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR);
				if (generator != null) {
					this.componentScanBeanNameGenerator = generator;
					this.importBeanNameGenerator = generator;
				}
			}
		}

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

		// 解析每个 @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 {
		    //这一步只会将加了通过@ComponentScan、@ComponentScans注解扫描的类才会加入到BeanDefinitionMap中
            // 通过其他注解(例如@Import、@Bean)的方式,在parse()方法这一步并不会将其解析为BeanDefinition放入到BeanDefinitionMap中,而是先解析成ConfigurationClass类
            // 真正放入到map中是在下面的this.reader.loadBeanDefinitions()方法中实现的
			parser.parse(candidates);
			//做校验 不能是final 
			// @Configuration 类中的实例 @Bean方法必须是可覆盖的以适应 CGLIB
			parser.validate();
			//获取解析的ConfigurationClass集合
			Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
			//移除已经解析过的
			configClasses.removeAll(alreadyParsed);

			//读取模型并根据其内容创建 bean 定义
			if (this.reader == null) {
				this.reader = new ConfigurationClassBeanDefinitionReader(
						registry, this.sourceExtractor, this.resourceLoader, this.environment,
						this.importBeanNameGenerator, parser.getImportRegistry());
			}
			//将上一步parser解析出的ConfigurationClass类加载成BeanDefinition
			//@Import、@ImportResource、@Bean或者、实现ImportBeanDefinitionRegistrar接口
			this.reader.loadBeanDefinitions(configClasses);
			alreadyParsed.addAll(configClasses);

			candidates.clear();
			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());

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

checkConfigurationClassCandidate(检查是否是配置类)

  • 检查给定的 bean 定义是否是配置类
  • 如果加了@Configuration,那么对应的BeanDefinition为full
  • 如果加了@Bean,@Component,@ComponentScan,@Import,@ImportResource这些注解,则为lite。像@Service、@Controller的注解里面都是加了@Component所以也是配置类
  • full和lite标记均表明是配置类
	public static boolean checkConfigurationClassCandidate(
			BeanDefinition beanDef, MetadataReaderFactory metadataReaderFactory) {

		String className = beanDef.getBeanClassName();
		if (className == null || beanDef.getFactoryMethodName() != null) {
			return false;
		}
		//根据不用的BeanDefinition获取元数据
		AnnotationMetadata metadata;
		if (beanDef instanceof AnnotatedBeanDefinition &&
				className.equals(((AnnotatedBeanDefinition) beanDef).getMetadata().getClassName())) {
			// Can reuse the pre-parsed metadata from the given BeanDefinition...
			metadata = ((AnnotatedBeanDefinition) beanDef).getMetadata();
		}
		else if (beanDef instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) beanDef).hasBeanClass()) {
			// Check already loaded Class if present...
			// since we possibly can't even load the class file for this Class.
			Class<?> beanClass = ((AbstractBeanDefinition) beanDef).getBeanClass();
			metadata = new StandardAnnotationMetadata(beanClass, true);
		}
		else {
			try {
				MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(className);
				metadata = metadataReader.getAnnotationMetadata();
			}
			catch (IOException ex) {
				if (logger.isDebugEnabled()) {
					logger.debug("Could not find class file for introspecting configuration annotations: " +
							className, ex);
				}
				return false;
			}
		}
		//含有@Configuration注解,那么对应的BeanDefinition的configurationClass属性值设置为full
		if (isFullConfigurationCandidate(metadata)) {
			beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);
		}
		// 含有@Bean,@Component,@ComponentScan,@Import,@ImportResource注解
		// configurationClass属性值设置为lite
		else if (isLiteConfigurationCandidate(metadata)) {
			beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);
		}
		else {
			return false;
		}
		...
		return true;
	}
  • isFullConfigurationCandidate(metadata)
	public static boolean isFullConfigurationCandidate(AnnotationMetadata metadata) {
		return metadata.isAnnotated(Configuration.class.getName());
	}
  • isLiteConfigurationCandidate(metadata)
	public static boolean isLiteConfigurationCandidate(AnnotationMetadata metadata) {
		// Do not consider an interface or an annotation...
		if (metadata.isInterface()) {
			return false;
		}

		// @Component,@ComponentScan,@Import,@ImportResource判断
		for (String indicator : candidateIndicators) {
			if (metadata.isAnnotated(indicator)) {
				return true;
			}
		}

		// @Bean 判断
		try {
			return metadata.hasAnnotatedMethods(Bean.class.getName());
		}
		catch (Throwable ex) {
			if (logger.isDebugEnabled()) {
				logger.debug("Failed to introspect @Bean methods on class [" + metadata.getClassName() + "]: " + ex);
			}
			return false;
		}
	}
	//candidateIndicators初始化
    private static final Set<String> candidateIndicators = new HashSet<>(8);

	static {
		candidateIndicators.add(Component.class.getName());
		candidateIndicators.add(ComponentScan.class.getName());
		candidateIndicators.add(Import.class.getName());
		candidateIndicators.add(ImportResource.class.getName());
	}

parser.parse(candidates);

  • 根据不同的BeanDefinition执行不一样的解析方法
  • parse里面最后都是调用processConfigurationClass
	public void parse(Set 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());
				}
			}
			catch (BeanDefinitionStoreException ex) {
				throw ex;
			}
			catch (Throwable ex) {
				throw new BeanDefinitionStoreException(
						"Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex);
			}
		}

		this.deferredImportSelectorHandler.process();
	}
  • parse首先会构建一个ConfigurationClass
	public ConfigurationClass(AnnotationMetadata metadata, String beanName) {
		Assert.notNull(beanName, "Bean name must not be null");
		this.metadata = metadata;
		// bean的描述
		this.resource = new DescriptiveResource(metadata.getClassName());
		this.beanName = beanName;
	}

processConfigurationClass

核心方法是doProcessConfigurationClass

	protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {
	    // 判断是否满足@Conditional的条件,满足条件给容器注册bean。
	    // 在文件附录中说明@Conditional
		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);
			}
		}

		// 递归处理配置类及其超类层次结构。
	    // 处理配置类,由于配置类可能存在父类(若父类的全类名是以java开头的,则除外),需要将configClass变成sourceClass去解析,然后返回sourceClass的父类。
	    // 如果此时父类为空,则不会进行while循环去解析,如果父类不为空,则会循环的去解析父类
	    // 如果无法理解,可以把它当做一个黑盒,不会影响看spring源码的主流程
		SourceClass sourceClass = asSourceClass(configClass);
		do {
			sourceClass = doProcessConfigurationClass(configClass, sourceClass);
		}
		while (sourceClass != null);
		// 将解析的配置类存储起来,这样回到parse()方法时,能取到值
		this.configurationClasses.put(configClass, configClass);
	}

doProcessConfigurationClass(重要)

  • 1.处理内部类,如果内部类也是一个配置类(包含@Configuration@Bean等)的话就在执行processConfigurationClass方法进行解析,里面还使用栈的处理方式防止ABA注入的问题
  • 2.处理属性资源文件,加了@PropertySource注解,将资源添加到environment中
    。例如@PropertySource({"demo.properties"})
  • 3.首先解析出类上的@ComponentScan和@ComponentScans注解(@SpringBootApplication里面就包含@ComponentScan注解),然后根据配置的扫描包路径,扫描出所有需要交给Spring管理的类,由于扫描出的类中可能也被加了@ComponentScan和@ComponentScans注解,因此需要进行递归解析,直到所有加了这两个注解的类被解析完成。过滤顺序:excludeFilters->includeFilters->false
  • 4.处理@Import注解,根据注解里面不同类型的值做不同的处理。@Import注解,支持三种方式。例如:@Configuration的配置类,实现ImportSelector或者ImportBeanDefinitionRegistrar的接口
  • 5.处理@ImportResource注解,解析配置文件注入bean。例如:@ImportResource("ioc/demo.xml")。这里会放到importedResources变量中。在外面的this.reader.loadBeanDefinitions(configClasses)加载定义的bean
  • 6.处理加了@Bean注解的方法,放到beanMethods变量中外面的this.reader.loadBeanDefinitions(configClasses)加载定义的bean
  • 7.通过processInterfaces()处理接口的默认方法,从JDK8开始,接口中的方法可以有自己的默认实现,因此,如果这个接口中的方法也加了@Bean注解,也需要被解析。和上面一样放到变量中在外面处理
  • 8.解析父类,如果被解析的配置类继承了某个类,那么配置类的父类也会被进行解析(父类是JDK内置的类例外,以java开头的)
	@Nullable
	protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)
			throws IOException {

		if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
			// 首先递归处理任何成员(嵌套)类
			processMemberClasses(configClass, sourceClass);
		}

		// 处理属性资源文件,加了@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");
			}
		}

		// 处理@ComponentScan或者@ComponentScans注解
		// @SpringBootApplication里面就包含@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) {
				// 配置类使用 @ComponentScan 注解 -> 立即执行扫描
				// 比如 basePackages = com.demo, 那么在这一步会扫描出这个包及子包下的class,然后将其解析成BeanDefinition
				// (BeanDefinition可以理解为等价于BeanDefinitionHolder)
				//parse最后调用DefaultListableBeanFactory中的registerBeanDefinition方法放到beanDefinitionMap中
				Set<BeanDefinitionHolder> scannedBeanDefinitions =
						this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
				// 通过上一步扫描包com.demo下的类,有可能扫描出来的bean中可能也添加了ComponentScan或者ComponentScans注解.
			    // 所以这里需要循环遍历一次,进行递归(parse)
				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());
					}
				}
			}
		}

		// 处理Import注解注册的bean,这一步只会将import注册的bean变为ConfigurationClass,不会变成BeanDefinition
	    // 而是在loadBeanDefinitions()方法中变成BeanDefinition,再放入到BeanDefinitionMap中
		processImports(configClass, sourceClass, getImports(sourceClass), true);

		// 处理@ImportResource注解引入的配置文件
		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);

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

this.reader.loadBeanDefinitions(configClasses)

  • 将上一步parser解析出的ConfigurationClass类加载成BeanDefinition
  • 包括@Import、@ImportResource、@Bean或者、实现ImportBeanDefinitionRegistrar接口
	/**
	 * Read {@code configurationModel}, registering bean definitions
	 * with the registry based on its contents.
	 */
	public void loadBeanDefinitions(Set<ConfigurationClass> configurationModel) {
		TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator();
		for (ConfigurationClass configClass : configurationModel) {
			loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);
		}
	}

	/**
	 * Read a particular {@link ConfigurationClass}, registering bean definitions
	 * for the class itself and all of its {@link Bean} methods.
	 */
	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;
		}

		if (configClass.isImported()) {
			registerBeanDefinitionForImportedConfigurationClass(configClass);
		}
		for (BeanMethod beanMethod : configClass.getBeanMethods()) {
			loadBeanDefinitionsForBeanMethod(beanMethod);
		}

		loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
		loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
	}

postProcessBeanFactory

该方法是对BeanFactory进行处理,主要干了两件事

  • (1)对加了@Configuration注解的类进行CGLIB代理。
  • (2)向Spring中添加一个后置处理器ImportAwareBeanPostProcessor。
	@Override
	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);
		}
        // 对加了@Configuration注解的配置类进行Cglib代理
		enhanceConfigurationClasses(beanFactory);
		// 添加一个BeanPostProcessor后置处理器
		beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
	}

enhanceConfigurationClasses

调用ConfigurationClassEnhancer.enhance()方法创建增强类

	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
	   ...
		ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer();
		for (Map.Entry<String, AbstractBeanDefinition> entry : configBeanDefs.entrySet()) {
			AbstractBeanDefinition beanDef = entry.getValue();
			// 如果 @Configuration 类被代理,总是代理目标类
			beanDef.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);
			try {
				// Set enhanced subclass of the user-specified bean class
				Class<?> configClass = beanDef.resolveBeanClass(this.beanClassLoader);
				if (configClass != null) {
				    // 调用ConfigurationClassEnhancer.enhance()方法创建增强类
					Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);
					if (configClass != enhancedClass) {
						if (logger.isTraceEnabled()) {
							logger.trace(String.format("Replacing bean definition '%s' existing class '%s' with " +
									"enhanced class '%s'", entry.getKey(), configClass.getName(), enhancedClass.getName()));
						}
						beanDef.setBeanClass(enhancedClass);
					}
				}
			}
			catch (Throwable ex) {
				throw new IllegalStateException("Cannot load configuration class: " + beanDef.getBeanClassName(), ex);
			}
		}
	}

ConfigurationClassEnhancer.enhance()方法

	public Class<?> enhance(Class<?> configClass, @Nullable ClassLoader classLoader) {
		if (EnhancedConfiguration.class.isAssignableFrom(configClass)) {
			if (logger.isDebugEnabled()) {
				logger.debug(String.format("Ignoring request to enhance %s as it has " +
						"already been enhanced. This usually indicates that more than one " +
						"ConfigurationClassPostProcessor has been registered (e.g. via " +
						"). This is harmless, but you may " +
						"want check your configuration and remove one CCPP if possible",
						configClass.getName()));
			}
			return configClass;
		}
		Class<?> enhancedClass = createClass(newEnhancer(configClass, classLoader));
		if (logger.isTraceEnabled()) {
			logger.trace(String.format("Successfully enhanced %s; enhanced class name is: %s",
					configClass.getName(), enhancedClass.getName()));
		}
		return enhancedClass;
	}

ConfigurationClassEnhancer.newEnhancer()方法

private static final Callback[] CALLBACKS = new Callback[] {
			new BeanMethodInterceptor(),
			new BeanFactoryAwareMethodInterceptor(),
			NoOp.INSTANCE
};
private static final ConditionalCallbackFilter CALLBACK_FILTER = new ConditionalCallbackFilter(CALLBACKS);
/**
 * Creates a new CGLIB {@link Enhancer} instance.
 */
private Enhancer newEnhancer(Class<?> configSuperClass, @Nullable ClassLoader classLoader) {
	Enhancer enhancer = new Enhancer();
    // CGLIB的动态代理基于继承
	enhancer.setSuperclass(configSuperClass);
    // 为新创建的代理对象设置一个父接口,EnhancedConfiguration继承BeanFactoryAware,主要目的是增加接口BeanFactoryAware
	enhancer.setInterfaces(new Class<?>[] {EnhancedConfiguration.class});
	enhancer.setUseFactory(false);
	enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
	enhancer.setStrategy(new BeanFactoryAwareGeneratorStrategy(classLoader));
	// 增强器可以理解为是对被增强类的对象进行了增强,比如在方法调用前后做拦截等等,
	// 添加了两个MethodInterceptor。(BeanMethodInterceptor和BeanFactoryAwareMethodInterceptor)
	// 通过这两个类的名称,前者是对加了@Bean注解的方法进行增强,后者是为代理对象的beanFactory属性进行增强
	enhancer.setCallbackFilter(CALLBACK_FILTER);
	enhancer.setCallbackTypes(CALLBACK_FILTER.getCallbackTypes());
	return enhancer;
}
  • BeanMethodInterceptor:拦截任何 {@link Bean} 注释方法的调用,以确保正确处理 bean 语义,例如@Bean 方法是非静态的
  • BeanFactoryAwareMethodInterceptor:判断超类是否实现了 BeanFactoryAware?如果是这样,调用它的 setBeanFactory() 方法
  • CGLIB创建动态代理是基于继承来是实现的(JDK的动态代理是基于接口实现),因此enhancer.setSupperclass(configSuperClass)这一行代码,就是为即将产生的代理对象设置父类,同时为产生的代理对象实现EnhancedConfiguration.class接口,实现该接口的目的,是为了该Configuration类在实例化、初始化过程中,执行相关的BeanPostProcessor。
  • 例如在执行ImportAwareBeanPostProcessor后置处理器时,postProcessPropertyValues()方法,会对EnhancedConfiguration类进行属性设置,实际就是为EnhancedConfiguration实现类的beanfactory属性赋值

ImportAwareBeanPostProcessor后置处理器

  • 在为bean填充属性的时候有个方法populateBean,如果是InstantiationAwareBeanPostProcessor类型就会使用postProcessProperties方法,子类ImportAwareBeanPostProcessor中的postProcessProperties就是为EnhanceConfiguration类的beanFactory属性赋值。
  • 对添加了@Configuration的类,如果实现了ImportAware接口就可以获取AnnotationMetadata信息
	private static class ImportAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter {

		private final BeanFactory beanFactory;

		public ImportAwareBeanPostProcessor(BeanFactory beanFactory) {
			this.beanFactory = beanFactory;
		}

		@Override
		public PropertyValues postProcessProperties(@Nullable PropertyValues pvs, Object bean, String beanName) {
			// Inject the BeanFactory before AutowiredAnnotationBeanPostProcessor's
			// postProcessProperties method attempts to autowire other configuration beans.
			if (bean instanceof EnhancedConfiguration) {
				((EnhancedConfiguration) bean).setBeanFactory(this.beanFactory);
			}
			return pvs;
		}

		@Override
		public Object postProcessBeforeInitialization(Object bean, String beanName) {
			if (bean instanceof ImportAware) {
				ImportRegistry ir = this.beanFactory.getBean(IMPORT_REGISTRY_BEAN_NAME, ImportRegistry.class);
				AnnotationMetadata importingClass = ir.getImportingClassFor(bean.getClass().getSuperclass().getName());
				if (importingClass != null) {
					((ImportAware) bean).setImportMetadata(importingClass);
				}
			}
			return bean;
		}
	}

你可能感兴趣的:(#,SB2源码学习,后置处理器,ComponentScan,Configuration,解析,springboot启动)