org.springframework.context.annotation.ConfigurationClassPostProcessor
org.springframework.context.event.DefaultEventListenerFactory
org.springframework.context.event.EventListenerMethodProcessor
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
org.springframework.context.annotation.CommonAnnotationBeanPostProcessor
经过查看这些内置的类,只有ConfigurationClassPostProcessor和类加载相关。
ConfigurationClassPostProcessor
主要用于对@Configuration注解进行处理。在SpringBoot应用中,往往都是从一个Main函数开始,启动类上面也必须使用@SpringBootApplication注解来标明它的身份;因此@Configuration注解也代表着应用的起点;因在BeanFactoryPostProcessor被调用的时候是按照优先级来的,首先被调用的是BeanDefinitionRegistryPostProcessor,所以首先执行postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)方法。
// ConfigurationClassPostProcessor.java
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);
}
① - 获取注册ID
② - 判断当前Processor是否被执行过
③ - 添加到已处理列表
④ - 处理配置相关的BeanDefinition
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
// 获取所有已注册的BeanDefinition,寻找具有@Configuration注解的类
String[] candidateNames = registry.getBeanDefinitionNames();
// 遍历所有的beanName
for (String beanName : candidateNames) {
// 根据名称找到BeanDefinition
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
// 判断当前类是Full模式还是Lite模式,就为了打印个日志?No,查看日志内容,打印的是:当前类已经被当做一个configuration类被处理过。
// 那就意味着默认情况下它是没有设置ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE 这个属性的。
if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) || ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
if (logger.isDebugEnabled()) {
logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
}
}
// 判断当前处理的类是不是完整的配置类,也就是是否被@Configuration注解修饰,若被修饰则会给当前的BeanDefinition设置一个attribute(org.springframework.context.annotation.ConfigurationClassPostProcessor.configurationClass = full)
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
// 加入配置候选列表
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
// 若没有被@Configuration注解的类,直接返回
// Return immediately if no @Configuration classes were found
if (configCandidates.isEmpty()) {
return;
}
// 根据优先级排序
// Sort by previously determined @Order value, if applicable
configCandidates.sort((bd1, bd2) -> {
int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
return Integer.compare(i1, i2);
});
// 设置BeanNameGenerator用于生成稍后检测到的Bean的名称
// 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) {
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注解的类
// Parse each @Configuration class
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 {
// ① 开始解析配置类
parser.parse(candidates);
parser.validate();
// ② 获取解析到的配置类
Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
configClasses.removeAll(alreadyParsed);
// ③ 构建Reader对象,为加载Bean做准备 Read the model and create bean definitions based on its content
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(
registry, this.sourceExtractor, this.resourceLoader, this.environment,
this.importBeanNameGenerator, parser.getImportRegistry());
}
// ④ 从配置类开始加载Bean
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();
}
}