【问题标题】:Bean definition is overriden by AutoConfigurationBean 定义被 AutoConfiguration 覆盖
【发布时间】:2018-10-18 09:19:25
【问题描述】:

在我的 Spring 应用程序中,我定义了一个 AuditListener 类型的 bean。

@Component
public class AuditListener {
}

我的项目还包含对spring-boot-starter-actuator 的依赖项,它还通过AuditAutoConfiguration 定义了AuditListener 类型的bean。

当我尝试启动我的应用程序时,它失败了,因为我自己的AuditListener 不可用。

// successful
beanFactory.getBean(org.springframework.boot.actuate.audit.listener.AuditListener.class);

// fails with NoSuchBeanDefinitionException
beanFactory.getBean(demo.AuditListener.class);

例外:

java.lang.IllegalStateException: Failed to execute ApplicationRunner
    at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:791)
    at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:778)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:335)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1255)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1243)
    at demo.DemoApplication.main(DemoApplication.java:14)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'demo.AuditListener' available
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:347)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:334)
    at demo.DemoApplication.run(DemoApplication.java:27)
    at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:788)
    ... 11 more

DefaultListableBeanFactory 日志

INFO 10140 --- [主] o.s.b.f.s.DefaultListableBeanFactory : 用不同的方法覆盖 bean 'auditListener' 的 bean 定义 定义:替换[通用bean:类[demo.AuditListener]; 范围=单例;摘要=假;懒惰初始化=假;自动线模式=0; 依赖检查=0;自动接线候选=真;主要=假; 工厂BeanName=空;工厂方法名=空;初始化方法名=空; 销毁方法名=空;在文件中定义 [C:\workspace\spring-autoconfiguration-conflict-demo\target\classes\demo\AuditListener.class]] 与 [根 bean: 类 [null];范围=;摘要=假;懒惰初始化=假; 自动线模式=3;依赖检查=0;自动接线候选=真; 主要=假; factoryBeanName=org.springframework.boot.actuate.autoconfigure.audit.AuditAutoConfiguration; factoryMethodName=审计监听器;初始化方法名=空; destroyMethodName=(推断);在类路径资源中定义 [org/springframework/boot/actuate/autoconfigure/audit/AuditAutoConfiguration.class]]

如何在不重命名自己的情况下将两个 AuditListener bean 放入我的上下文中?

编辑:如果我在不同的包中定义两个具有相同类名的 bean,我会得到一个 ConflictingBeanDefinitionException,因此 ApplicationContext 甚至不会启动。

【问题讨论】:

  • 这不是 Spring 的 @Qualifier 注释的用例吗? spring.io/blog/2014/11/04/a-quality-qualifier
  • 您是否反对重命名您的 bean 或您的类?如果你可以重命名你的 bean,那么 @Component("myAuditListener")@Qualifier 注入它。

标签: java spring spring-boot


【解决方案1】:

如果自动配置添加了具有相同 bean 名称的 bean,Spring 将从上下文中删除您自己的 bean。这是标准的 Spring Framework 行为。当声明了多个同名的 bean 时,最后一个声明的将获胜。框架应记录一条信息消息,让您知道发生了覆盖。

【讨论】:

    【解决方案2】:

    您可以为您的 bean 命名,这样它就不会与 SpringBoot bean 冲突

    @Component(value = "myCustomAuditListener ")
    public class AuditListener {
    }
    

    然后使用@Qualifies通过名字myCustomAuditListener注入它

    【讨论】:

      猜你喜欢
      • 2023-01-25
      • 1970-01-01
      • 1970-01-01
      • 2016-06-08
      • 1970-01-01
      • 1970-01-01
      • 2013-10-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多