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));
}
}
}
//。。。。。。
}
}
……未完待续 还有好多 比如postProcessBeanFactory这个方法又干了好多事情