Spring|Spring Boot @Component @Configuration 同时声明一个对象会怎样呢()
先贴出示例:
文章图片
文章图片
接下来开始分析过程,启动项目,会发现ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry()执行我们声明的目标类:
文章图片
文章图片
图1-2
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
List configCandidates = new ArrayList<>();
String[] candidateNames = registry.getBeanDefinitionNames();
for (String beanName : candidateNames) {
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
if (logger.isDebugEnabled()) {
logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
}
}
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}// 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);
});
// 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();
}// Parse each @Configuration class
//创建ConfigurationClassParser类,用来解析带有@Configuration的类
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
Set candidates = new LinkedHashSet<>(configCandidates);
Set alreadyParsed = new HashSet<>(configCandidates.size());
do {
//执行解析逻辑
parser.parse(candidates);
parser.validate();
//保存所有带@Configuration的类
Set configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
configClasses.removeAll(alreadyParsed);
// Read the model and create bean definitions based on its content
if (this.reader == null) {
//声明@configuration读取类
this.reader = new ConfigurationClassBeanDefinitionReader(
registry, this.sourceExtractor, this.resourceLoader, this.environment,
this.importBeanNameGenerator, parser.getImportRegistry());
}
//加载
this.reader.loadBeanDefinitions(configClasses);
alreadyParsed.addAll(configClasses);
candidates.clear();
if (registry.getBeanDefinitionCount() > candidateNames.length) {
String[] newCandidateNames = registry.getBeanDefinitionNames();
Set oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
Set 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();
}
}
其中reader.loadBeanDefinitions(configClasses),最终调用loadBeanDefinitionsForConfigurationClass()
private void loadBeanDefinitionsForConfigurationClass(
ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {
for (BeanMethod beanMethod : configClass.getBeanMethods()) {
//加载@Configuration类中的带@Bean的方法
loadBeanDefinitionsForBeanMethod(beanMethod);
}
}
private void loadBeanDefinitionsForBeanMethod(BeanMethod beanMethod) {
//将@Bean的所在方法的类,注册进DefaultListBeanFactory的beanDefinitionMap中
this.registry.registerBeanDefinition()
}
【Spring|Spring Boot @Component @Configuration 同时声明一个对象会怎样呢()】DefaultListBeanFactory.registerBeanDefinition(); 具体细节
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
BeanDefinition oldBeanDefinition;
//因为之前的parser已经解析到userManager,此时解析UserConfig中的UserManager会发现 oldBeanDefinition 不为空;
oldBeanDefinition = this.beanDefinitionMap.get(beanName);
if (oldBeanDefinition != null) {
if (!isAllowBeanDefinitionOverriding()) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +
"': There is already [" + oldBeanDefinition + "] bound.");
}
else if (oldBeanDefinition.getRole() < beanDefinition.getRole()) {
// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
if (this.logger.isWarnEnabled()) {
this.logger.warn("Overriding user-defined bean definition for bean '" + beanName +
"' with a framework-generated bean definition: replacing [" +
oldBeanDefinition + "] with [" + beanDefinition + "]");
}
}
else if (!beanDefinition.equals(oldBeanDefinition)) {
if (this.logger.isInfoEnabled()) {
this.logger.info("Overriding bean definition for bean '" + beanName +
"' with a different definition: replacing [" + oldBeanDefinition +
"] with [" + beanDefinition + "]");
}
}
else {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Overriding bean definition for bean '" + beanName +
"' with an equivalent definition: replacing [" + oldBeanDefinition +
"] with [" + beanDefinition + "]");
}
}
//新的beanDefinition会替换为老的beanDefinition
this.beanDefinitionMap.put(beanName, beanDefinition);
}
}
结果就是:
文章图片
oldBeanDefinition被替换掉;
推荐阅读
- #yyds干货盘点#30个类手写Spring核心原理之AOP代码织入
- 为什么Bootstrap网格不起作用,而按钮却起作用()
- Java毕业设计项目实战篇|springBoot redis开发的Java快递代拿系统(含人脸识别,验证码登录)
- spring-boot-devtools 快速重启的秘密!#yyds干货盘点#
- Spring的七大模块#yyds干货盘点#
- SpringBoot整合Redis 之 lettuce#私藏项目实操分享#
- #私藏项目实操分享#SpringCloud技术专题「Gateway网关系列」微服务网关服务的Gateway功能配置指南分析
- Spring认证中国教育管理中心-Apache Cassandra 的 Spring 数据
- shiro|Spring Boot 极简集成 Shiro
- SpringBoot|接入Swagger2(2) —— knife4j