【问题标题】:how to use @Qualifier to identify the bean that should be consumed如何使用@Qualifier 来识别应该使用的bean
【发布时间】:2021-09-08 17:03:59
【问题描述】:

我想使用组件类之一中的 WebServiceTemplate 对象,但在两个配置类中声明,下面是代码

@Configuration
public class EddClientConfig {
    @Bean
    public WebServiceTemplate eddTemplate(Jaxb2Marshaller jaxb2EprsMarshaller) {
        ........  
    }
}

@Configuration
public class ProposalClientConfig {
    
    @Bean
    public WebServiceTemplate ProposalTemplate(Jaxb2Marshaller jaxb2EprsMarshaller) {
        ........
        
    }
}

@Component
public class ProposalDataClientImpl implements  ProposalDataClient{
......
    @Autowired
    private WebServiceTemplate eddTemplate;
......
}

错误是

EddClientConfig 中方法 eddTemplate 的参数 0 需要一个 bean,但找到了 2 个:
- jaxb2EddMarshaller:由类路径资源中的“jaxb2EddMarshaller”方法定义 [....EddClientConfig.class]
- jaxb2PropposalDataMarshaller:由类路径资源中的方法 'jaxb2PropposalDataMarshaller' 定义 [...../ProposalDataClientConfig.class]

我的 Gradle.build 文件

dependencies {
compile(project(':edd-connector')) // EddClientConfig class exists here
compile(project(':proposal-connector')) //ProposalClientConfig class exists here
......
}

我尝试了什么

@Configuration
public class EddClientConfig {
    @Bean(name = "eddTemplate")
    public WebServiceTemplate eddTemplate(Jaxb2Marshaller jaxb2EprsMarshaller) {
        ........  
    }
}

@Configuration
public class ProposalClientConfig {
    
    @Bean(name = "ProposalTemplate")
    public WebServiceTemplate ProposalTemplate(Jaxb2Marshaller jaxb2EprsMarshaller) {
        ........     
    }
}

@Component
public class ProposalDataClientImpl implements  ProposalDataClient{
......
    @Autowired
    @Qualifier("ProposalTemplate")
    private WebServiceTemplate eddTemplate;
......
}

但没有运气。让我知道我做错了什么。提前致谢。

【问题讨论】:

  • 是否有 2 个Jaxb2Marshaller bean 可用?控制台中是否提到了 bean 名称?
  • 我同意@SKumar,它的Jaxb2Marshaller 可能有2 个实现,而Spring 不知道要注入哪一个,问题可能不在你的bean 中尝试找到这个Jaxb2Marshaller。还分享您的pom.xml 可能是一个依赖项带来了额外的实现,或者您是否在某处使用@Beans 定义了它以及如何定义它?
  • @SKumar,是的 2 个 Jaxb2Marshller bean 在两个不同的模块中可用,我需要两个模块,所以我在我的构建 gradle 文件中编译这两个模块。所以歧义正在发生。请让我知道如何解决此错误。
  • @pleft,感谢您的评论。我附上了我的 gradle 文件和完整的错误。
  • @kodali 请贴出配置类ProposalClientConfigEddClientConfig的完整代码

标签: java spring spring-boot qualifiers


【解决方案1】:

EddClientConfig 中方法 eddTemplate 的参数 0 需要一个 bean,但找到了 2 个

@Configuration
public class EddClientConfig {
    // this is the method in the trace
    @Bean(name = "eddTemplate")
    // parameter 0 = jaxb2EprsMarshaller --> there are 2 impl of this bean in your app context
    public WebServiceTemplate eddTemplate(Jaxb2Marshaller jaxb2EprsMarshaller) {
        
    }
}

您需要查看这些 bean 在您的自动配置中创建的位置,或者创建您自己的 Jaxb2Marshaller 类型的 bean 并使用它。

【讨论】:

  • 是的,你说得对。我有两个 bean,它们来自我正在导入模块的两个模块。请让我知道如何指定我只需要特定的实现。
  • 找出 bean 是什么,并在方法签名中添加 @Qualifier("bean name"),如建议的 @SKumar
  • 这条评论很有用。
  • 谢谢 - 如果这足够了,请接受,如果您有更多问题,请接受 lmk
  • SKumar 对我来说已经足够回答了。
【解决方案2】:

EddClientConfig 中方法 eddTemplate 的参数 0 需要单个 bean,但找到了 2 个:

  • jaxb2EddMarshaller:由类路径资源 [....EddClientConfig.class] 中的方法 'jaxb2EddMarshaller' 定义
  • jaxb2PropposalDataMarshaller:由类路径资源中的方法 'jaxb2PropposalDataMarshaller' 定义 [...../ProposalDataClientConfig.class]

如果您使用带有 bean 名称的 Qualifier,该异常应该会消失,就像您在 ProposalDataClientImpl 中尝试的方式一样。因为,有 2 个 bean - jaxb2EddMarshallerjaxb2PropposalDataMarshaller。我们可以像下面这样使用它们,这样 Spring 就会知道 eddTemplate 应该使用 jaxb2EddMarshaller 而另一个配置是另一个 Marshaller -

@Configuration
public class EddClientConfig {
    @Bean(name = "eddTemplate")
    public WebServiceTemplate eddTemplate(@Qualifier("jaxb2EddMarshaller")Jaxb2Marshaller jaxb2EprsMarshaller) {
        ........  
    }
}

@Configuration
public class ProposalClientConfig {

    @Bean(name = "ProposalTemplate")
    public WebServiceTemplate ProposalTemplate(@Qualifier("jaxb2PropposalDataMarshaller")Jaxb2Marshaller jaxb2EprsMarshaller) {
        ........     
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-09
    • 2017-10-02
    • 2020-03-21
    • 2023-02-15
    • 2018-08-14
    相关资源
    最近更新 更多