spring-系列
文章目录
前言
ConfigurationClassPostProcessor是BeanDefinitionRegistryPostProcessor接口的实现类。spring通过@Configuration注解加载Bean的具体实现,该类将全面解剖@Configuration注解的神秘面纱。在阅读本文之前读者需要知道什么是BeanDefinitionRegistryPostProcessor,如果还有疑问请移步。
ConfigurationClassPostProcessor
public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor,
PriorityOrdered, ResourceLoaderAware, ApplicationStartupAware, BeanClassLoaderAware, EnvironmentAware {
}
该类是BeanDefinitionRegistryPostProcessor接口扩展的一个经典案例,实现了PriorityOrdered来优先加载@Configuration的Bean,核心入口是BeanDefinitionRegistryPostProcessor接口的postProcessBeanDefinitionRegistry方法,下面详细讨论。
postProcessBeanDefinitionRegistry
/**
* 加载外部定义的Bean,该方法是Configuration,Bean,Component,Service,Import等注解加载Bean的入口
* @param registry the bean definition registry used by the application context
*/
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
/**
* 获取registry注册器hashcode的值
*/
int registryId = System.identityHashCode(registry);
/**
* 验证该注册器是否已注册该Bean,表示一个注册器只能注册一次ConfigurationClassPostProcessor
*/
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);
/**
* 执行外部Bean的注册逻辑
*/
processConfigBeanDefinitions(registry);
}
processConfigBeanDefinitions(registry)是真正处理Bean的方法。
processConfigBeanDefinitions
/**
* 处理Configuration的Bean加载逻辑
* @param registry
*/
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
/**
* 存储所有被Configuration注解修饰的类
*/
List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
/**
* 获取当前所有bean名称
*/
String[] candidateNames = registry.getBeanDefinitionNames();
for (String beanName : candidateNames) {
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
if (logger.isDebugEnabled()) {
logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
}
}
/**
* 检查当前是否是一个标准的Bean(检查当前类是否被 Configuration, Component,ComponentSpan,Import,ImportResource 注解修饰)
*/
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
// Return immediately if no @Configuration classes were found
/**
* 如果未找到@Configuration类,则立即返回
*/
if (configCandidates.isEmpty()) {
return;
}
// Sort by previously determined @Order value, if applicable、
/**
* 对所有Configuration修饰的类进行排序
*/
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
/**
* 检测上下文提供的任何自定义bean名称生成策略,
*/
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) {
this.componentScanBeanNameGenerator = generator;
this.importBeanNameGenerator = generator;
}
}
}
/**
* 给environment赋初始值
*/
if (this.environment == null) {
this.environment = new StandardEnvironment();
}
// Parse each @Configuration class
/**
* 创建 @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 {
StartupStep processConfig = this.applicationStartup.start("spring.context.config-classes.parse");
/**
* 解析被@Configuration修饰的Bean
*/
parser.parse(candidates);
/**
* 验证被@Configuration 注解修饰的类不能被Final修饰
* 验证被@Bean 注解修饰的方法可以被重写
*/
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(
registry, this.sourceExtractor, this.resourceLoader, this.environment,
this.importBeanNameGenerator, parser.getImportRegistry());
}
/**
* 通过配置类来加载Bean,这是真正加载Bean的入口
*/
this.reader.loadBeanDefinitions(configClasses);
/**
* 加载的类标记为已加载
*/
alreadyParsed.addAll(configClasses);
processConfig.tag("classCount", () -> String.valueOf(configClasses.size())).end();
candidates.clear();
if (registry.getBeanDefinitionCount() > candidateNames.length) {
String[] newCandidateNames = registry.getBeanDefinitionNames