当前位置: 首页 > 知识库问答 >
问题:

当使用@Qualifier指定的bean注入点时,如何扩展命名的Spring bean?

寿卜鹰
2023-03-14

当使用@Qualifier指定的bean注入点时,如何扩展命名bean?

我的项目1由3个spring Bean组成:

@Component("bean1")
public class Bean1 implements Bean {
}

@Component("bean2")
public class Bean2 implements Bean {
}

@Component("bean3")
public class Bean3 {
    private Bean bean;

    public void setBean(@Qualifier("bean1") final Bean bean) {
        this.bean = bean;
    }
}

这个项目被捆绑到一个jar中,并作为我的第二个项目的依赖项包含在内:

@Component("bean1")
@Primary
public class Bean1Child extends Bean1 {
}

我想发生的是将beanBean1Child注入到Bean3的setter方法中。不幸的是,我收到了一个错误。

组织。springframework。上下文注释。冲突BeanDefinitionException:bean类[Bean1Child]的注释指定的bean名称“bean1”与相同名称和类[bean1]的现有不兼容bean定义冲突

我需要使用@Qualifier以便Bean2不会注入Bean3使用@主注释没有帮助。从我的第二个项目运行时,如何将Bean1Child注入Bean3

共有3个答案

暴骏奇
2023-03-14

您有多个相同类型的bean,并且希望防止注入Bean2。在一些项目中注入Bean1,在其他项目中注入Bean1Child。

有多种选择。

使用bean,使Bean1Child定义与Bean1定义相同

@Configuration
public class Config {

  @Primary
  @Bean
  public Bean1 bean1() { //return type must be Bean1
    return new Bean1Child();
  }
}

并设置属性“Spring”。主要的允许bean定义覆盖=true

@Qualifier
@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@interface BeanType {

}

@BeanType
public @interface Bean1Type {
}

@Bean1Type
@Component("bean1")
public class Bean1 implements Bean {
}

@Component("bean2")
public class Bean2 implements Bean {
}

@Component("bean3")
public class Bean3 {

  private final Bean bean;

  public Bean3(@Bean1Type Bean bean) {
    this.bean = bean;
  }
}

@Bean1Type
@Primary
@Component("bean1Child")
public class Bean1Child extends Bean1 {

}
井轶
2023-03-14

您可以使用ConditionalOnMissingBean特性轻松实现这一点。

修改你的Bean1类如下

@Component("bean1")
@ConditionalOnMissingBean(type = "bean1")
public class Bean1 implements Bean {
}

修改Bean1Child类如下

@Component
@Qualifier("bean1")
@Primary
public class Bean1Child extends Bean1 {
}

它是如何工作的?

  • Spring将尝试加载名为“bean1”的bean。如果它没有找到任何具有相同名称且标记为主的bean,它将返回到Bean1类并将其加载为“Bean1”
  • 必须将Bean1Child标记为primary,因为spring将找到两个同名的bean。我们需要知道加载哪个
危卜鹰
2023-03-14

如果可能,可以通过删除组件注释来更改bean的创建方式:

在第一个项目中,将重构BeanChild3,以在构造函数中获得bean

public class Bean3 {
    private final Bean bean;

    public Bean3(final Bean bean) {
        this.bean = bean;
    }
}

然后我们可以在BeansConfig类中创建bean

java prettyprint-override">@Configuration
class BeansConfig {

   @ConditionalOnMissingBean
   @Bean("bean1")
   Bean bean1(){
      return new Bean1();
   }

   @Bean("bean2")
   Bean bean2(){
      return new Bean2();
   }

   @Bean("bean3")
   Bean bean3(@Autowired @Qualifier("bean1") Bean){
      return new Bean3(bean);
   }

}

@ConditionalOnMissingBean允许我们提供另一个具有相同名称的bean来代替。如果不存在这样的bean,那么将使用默认bean。

然后,您将需要在您的第二个项目中创建一个beanChild1bean,并且应该将其拾取。

   @Bean("bean1")
   Bean bean1(){
      return new Bean1Child();
   }
 类似资料:
  • 我有以下类 : 我想按如下方式使用它: 因此,通过扩展已经注入依赖项的超类,我希望在其子类中访问它。 我尝试了许多不同的方法,甚至将超类作为组件: 但是,<code>仍然是这样。fetchApi为,即使在超类中也是如此。

  • 所以我有两个集成测试类。我正在使用flyway测试扩展重置db。当我从IntelliJ单独运行测试类时,两个都通过了。然而,当我使用mvn clean install或在IntelliJ all test中一起运行它们时,TestClass2会出现异常并失败。 创建名为“flywayInitializer”的bean时出错,该bean在类路径资源[org/springframework/boot/

  • 我有以下命名元组: 然后我想要以下内容: 两个名称元组之间有重复,我如何子类ReadElement以包含一个附加字段? 然而元组是创建在那里的,那么在新语句中,如果我修改自我成为一个列表,我会失去类型信息,我该如何避免这种情况?

  • 我正在使用RDF/XML在tripplestore(GraphDb)中插入tripples。这是可行的,但我也需要将所有tripples收集到一个唯一的命名图中,我正在寻找RDF/XML中的正确语法来实现这一点,在插入数据时,总是使用相同的名称作为图(类似于“http://domain_com/graphName"). 我找到的唯一文件就是这个https://www.w3.org/2009/07/

  • 问题内容: BigQuery支持重复数据删除以进行流插入。如何通过Apache Beam使用此功能? https://cloud.google.com/bigquery/streaming-data-into- bigquery#dataconsistency 为了帮助确保数据一致性,可以为每个插入的行提供insertId。BigQuery会记住此ID至少一分钟。如果您尝试在该时间段内流传输相同的

  • 如题 编译php-7.4.30 在编译的时候使用命令 提示不支持 求解如何设置