Spring源码分析(六)常用BeanFactoryPostProcessor扩展

ConfigurationClassPostProcessor

  ConfigurationClassPostProcessor实现了BeanDefinitionRegistryPostProcessor接口(BeanFactoryPostProcessor的子接口),在applicationContext的refresh过程中,负责解析@Configuration、@ComponentScan、@ComponentScans、@Import、@ImportResource、@Bean、@PropertySource、@PropertySources注解。

处理lite配置类

public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor, PriorityOrdered {
	public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
		int registryId = System.identityHashCode(registry);
		if (this.registriesPostProcessed.contains(registryId)) {
			throw new IllegalStateException(...);
		}
		if (this.factoriesPostProcessed.contains(registryId)) {
			throw new IllegalStateException(...);
		}
		this.registriesPostProcessed.add(registryId);

		// 处理配置类
		processConfigBeanDefinitions(registry);
	}

	public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
		List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
		
		// 遍历所有的BeanDefinition(手动注册的单例不会被处理,即没有注册为BeanDefinition),筛选出未曾处理过的配置类
		String[] candidateNames = registry.getBeanDefinitionNames();
		for (String beanName : candidateNames) {
			BeanDefinition beanDef = registry.getBeanDefinition(beanName);
			if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
				// 如果某个BeanDefinition包含了指定属性,那么就说明这个类已经被处理过,不用筛选出来,代码只是打印了log
			} else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
				// 判断一个BeanDefinition是否是配置类(配置类有full与lite两种类型,但他们都属于配置类)
				// 如果类被@Configuration标记,且proxyBeanMethods属性不为false,那么它是full类型的配置类
				// 如果类被@Configuration标记,且proxyBeanMethods属性为false,那么它是lite类型的配置类
				// 如果类被@Component、@ComponentScan、@Import、@ImportResource标记,那么它是lite类型的配置类
				// 如果类有被@Bean标记的方法,那么它是lite类型的配置类
				// 其他情况就不是配置类,可见配置类不一定需要被@Configuration标记

				// 如果是配置类,那么就筛选出来
				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);
		});

		// 可以从单例Bean中获取指定名的BeanNameGenerator来覆盖默认的BeanNameGenerator
		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) {
					// 默认AnnotationBeanNameGenerator,以简单类名首字母小写作为beanName
					this.componentScanBeanNameGenerator = generator;
					// 默认FullyQualifiedAnnotationBeanNameGenerator,以类全名作为beanName
					this.importBeanNameGenerator = generator;
				}
			}
		}

		// 在没有环境是创建环境
		if (this.environment == null) {
			this.environment = new StandardEnvironment();
		}

		// 用来解析候选配置类
		ConfigurationClassParser parser = new ConfigurationClassParser(
				this.metadataReaderFactory, this.problemReporter, this.environment,
				this.resourceLoader, this.componentScanBeanNameGenerator, registry);
		// candidates保存待处理的配置类,alreadyParsed保存已处理的配置类
		Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
		Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
		do {
			// 完成@ComponentScan、@ComponentScans、@PropertySource、@PropertySources、@Import的处理
			// 解析@ImportResource、@Bean到ConfigurationClass,但它们没有被处理
			parser.parse(candidates);
			parser.validate();

			// 进一步处理配置类(前面只将@ImportResource、@Bean注解的解析结果存入ConfiurationClass,现在对通过ConfiurationClass来处理这些注解)
			Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
			configClasses.removeAll(alreadyParsed);			
			if (this.reader == null) {
				this.reader = new ConfigurationClassBeanDefinitionReader(
						registry, this.sourceExtractor, this.resourceLoader, this.environment,
						this.importBeanNameGenerator, parser.getImportRegistry());
			}
			// 循环调用ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(...)处理每一个ConfigurationClass
			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());

		// 将ImportRegistry以单例形式发布出去
		if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
			sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
		}

		// 如果使用了缓存类型的注解解析器(解析注解时进行了缓存,以便提高重复解析的效率),兔死狗烹,清除掉缓存
		if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
			((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
		}
	}
}	

class ConfigurationClassParser {
	public void parse(Set<BeanDefinitionHolder> configCandidates) {
		for (BeanDefinitionHolder holder : configCandidates) {
			BeanDefinition bd = holder.getBeanDefinition();			
			// 所有的parse(...)方法最终都调用了processConfigurationClass(...)方法来解析配置类
			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(及DeferredImportSelector类型的ImportSelector)
		this.deferredImportSelectorHandler.process();
	}
	
	protected void processConfigurationClass(ConfigurationClass configClass, Predicate<String> filter) {
		// 通过ConditionEvaluator来忽略配置类的解析
		if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
			return;
		}
		
		...

		// 初始化时,SourceClass和ConfigurationClass代表的是同一个类
		SourceClass sourceClass = asSourceClass(configClass, filter);
		do {
			// ConfigurationClass代表的是配置类,而SourceClass代表的是处理类
			// 该方法返回的SourceClass是刚处理的SourceClass的父类(如果父类包名是以"java"开头的,则返回null)
			// 这样可以递归父类处理SourceClass,直到遇到java自己定义的类才放弃递归,整个过程中ConfigurationClass不变
			sourceClass = doProcessConfigurationClass(configClass, sourceClass, filter);
		} while (sourceClass != null);

		// 将解析后的ConfigurationClass缓存起来,这样可以获取
		this.configurationClasses.put(configClass, configClass);
	}

	protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter) {
		// 如果配置类被Component标记,那么会将其所有成员内部类也当做配置类递归调用processConfigurationClass(...)
		if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
			processMemberClasses(configClass, sourceClass, filter);
		}

		// 完成@PropertySource与PropertySources注解的解析和处理
		// 根据注解配置的资源路径将每一个properties资源封装为一个PropertySource并加入Environment
		for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
				sourceClass.getMetadata(), PropertySources.class, PropertySource.class)) {
			if (this.environment instanceof ConfigurableEnvironment) {
				processPropertySource(propertySource);
			} else {
				logger.info(...);
			}
		}

		// 完成@ComponentScan与ComponentScans注解的解析和处理
		// 根据配置的包名使用ClassPathBeanDefinitionScanner来进行处理,并对扫描到的新配置类进行递归处理
		Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
				sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
		// 如果有@ComponentScan与ComponentScans注解并且没有被Conditional忽略才进行处理
		if (!componentScans.isEmpty() &&
				!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
			for (AnnotationAttributes componentScan : componentScans) {
				Set<BeanDefinitionHolder> scannedBeanDefinitions =
						this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
				// 循环处理本次扫描到的配置类
				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的解析和处理,getImports(...)就是获取@Import导入的所有类
		processImports(configClass, sourceClass, getImports(sourceClass), filter, true);

		// 解析ImportResource注解,并将解析结果保存到configClass
		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并将解析结果保存在configClass
		Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
		for (MethodMetadata methodMetadata : beanMethods) {
			configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
		}
		// 由于Java8中默认方法的出现,此处会解析sourceClass实现的所有接口中被@Bean标记的方法并保存在configClass
		processInterfaces(configClass, sourceClass);

		// 返回新的SourceClass就是当前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);
				return sourceClass.getSuperClass();
			}
		}

		return null;
	}

	private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
			Collection<SourceClass> importCandidates, Predicate<String> exclusionFilter,
			boolean checkForCircularImports) {
		if (importCandidates.isEmpty()) {
			return;
		}

		if (checkForCircularImports && isChainedImportOnStack(configClass)) {
			// 循环导入抛错
			this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));
		} else {
			// 这里就是为了解决循环导入问题,在@Import处理过程前后分别入栈和出栈
			this.importStack.push(configClass);
			try {
				// 依次处理被导入的候选类,不同类型的候选类会有不同的处理方式
				for (SourceClass candidate : importCandidates) {
					if (candidate.isAssignable(ImportSelector.class)) {
						// 如果导入的是ImportSelector类型的处理
						Class<?> candidateClass = candidate.loadClass();
						ImportSelector selector = ParserStrategyUtils.instantiateClass(candidateClass, 
								ImportSelector.class, this.environment, this.resourceLoader, this.registry);
						
						// 如果被导入类是DeferredImportSelector类型,那么推迟执行
						if (selector instanceof DeferredImportSelector) {
							this.deferredImportSelectorHandler.handle(configClass, (DeferredImportSelector) selector);
						} else {
							// 以被导入类对象的selectImports(...)方法返回的类全名数组作为导入类递归调用
							String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
							Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames, exclusionFilter);
							processImports(configClass, currentSourceClass, importSourceClasses, exclusionFilter, false);
						}
					} else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
						// 如果被导入的是ImportBeanDefinitionRegistrar类型,解析出配置留在ConfigurationClassBeanDefinitionReader中处理
						Class<?> candidateClass = candidate.loadClass();
						ImportBeanDefinitionRegistrar registrar = ParserStrategyUtils.instantiateClass(candidateClass, 
								ImportBeanDefinitionRegistrar.class, this.environment, this.resourceLoader, this.registry);
						configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
					} else {
						// 如果被导入的不是以上列出的类型,直接把导入的类当做配置类处理(ConfigClass的importBy就是导入它的配置类)
						// 被导入的类不会在此处注册为BeanDefinition,但在后面ConfigurationClassBeanDefinitionReader会注册
						this.importStack.registerImport(
								currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
						processConfigurationClass(candidate.asConfigClass(configClass), exclusionFilter);
					}
				}
			} finally {
				this.importStack.pop();
			}
		}
	}
}

class ConfigurationClassBeanDefinitionReader {
	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;
		}

		// 如果当前配置类是被导入的,那么根据配置类的注解信息来生成BeanDefinition并注册
		if (configClass.isImported()) {
			registerBeanDefinitionForImportedConfigurationClass(configClass);
		}
		
		// 依次处理所有BeanMethod(被@Bean标记的方法)
		for (BeanMethod beanMethod : configClass.getBeanMethods()) {
			// 针对每一个BeanMethod创建一个ConfigurationClassBeanDefinition(会使用ConditionEvaluator进行过滤)
			// BeanDefinition的factoryMethodName属性设置为当前BeanMethod代表的方法名
			// 如果是静态方法就将beanClassName设置为配置类的类全名,否则将factoryBeanName设置为配置类的beanName
			// 以@Bean的属性及其他注解(@Scope、@Lazy等)来初始化BeanDefinition的相应字段
			loadBeanDefinitionsForBeanMethod(beanMethod);
		}

		// 对于Java程序直接使用XmlBeanDefinitionReader来解析导入的资源(其他语言如groovy使用其他解析器)
		loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
		// 直接调用所有ImportBeanDefinitionRegistrar的registerBeanDefinitions(...)方法
		loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
	}
}

处理full配置类

public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor {
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		int factoryId = System.identityHashCode(beanFactory);
		if (this.factoriesPostProcessed.contains(factoryId)) {
			throw new IllegalStateException(...);
		}
		this.factoriesPostProcessed.add(factoryId);
		
		// 确保先执行了processConfigBeanDefinitions(...)方法
		if (!this.registriesPostProcessed.contains(factoryId)) {
			processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
		}

		// 将所有full配置类的BeanDefinition的类型替换为ConfigurationClassEnhancer创建的代理类
		enhanceConfigurationClasses(beanFactory);

		// 注册ImportAware感知接口的处理器
		beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
	}
}	
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值