报错信息
springboot项目启动报错:Error starting ApplicationContext. To display the conditions report re-run your application with ‘debug’ enabled. 2022-03-28 16:55:30.412 ERROR 10564 — [ main] o.s.b.d.LoggingFailureAnalysisReporter :
APPLICATION FAILED TO START
Description:
The bean ‘redisTemplate’, defined in class path resource [com/uhu/redis/config/RedisConfig.class], could not be registered. A bean with that name has already been defined in class path resource [org/springframework/boot/autoconfigure/data/redis/RedisAutoConfiguration.class] and overriding is disabled.
Action:
Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true
出错分析
我们有很多应用程序依赖于覆盖现有 Spring bean 的模块。升级到 spring-boot 2.1.0 后,应用程序无法再启动,因为 spring.main.allow-bean-definition-overriding=true 必须设置。
默认情况下,单个配置文件中存在id或者name相同的bean定义,spring解析时会报错;不同配置文件中存在id或者name相同的bean定义,后面加载的bean定义会覆盖前面的bean定义
springboot启动,默认allow-bean-definition-overriding为false,我们需要修改为true。 加载redisTemplate时候发现已存在相同名称的bean,查看allow-bean-definition-overriding=false,故抛出异常。 我们项目使用的nacos配置中心,发现将spring.main.allow-bean-definition-overriding=true配置到nacos中,系统启动还是报错,而配置到bootstrap.yml或者application.yml中则程序正常启动。
跟随springboot启动流程,首先启动加载spring的配置环境及springcloud的环境,这里主要是我们的bootstrap.yml。 准备上下文的时候,设置allow-bean-definition-overriding,此时值=false
可以看到allowBeanDefinitionOverriding默认为false。 nacos读取配置后没有刷新该值,故只能配置在application.yml或者bootstrap.yml中,交由spring初始化加载。
解决方案
1.配置到bootstrap.yml或者application.yml中 2.实现EnvironmentPostProcessor并设置值,并在META-INF中注入我们的类 org.springframework.boot.env.EnvironmentPostProcessor=package.name.YourClassname
@Override
public void postProcessEnvironment(final ConfigurableEnvironment environment, final SpringApplication application) {
application.setAllowBeanDefinitionOverriding(true);
}
再次debugger可以看到allowBeanDefinitionOverriding=true
|