方法名称相同但限定符不同的Spring Bean无法加载

时间:2019-02-16 20:01:41

标签: spring

我有两个定义如下的Spring Configuration类

@Configuration
public class ClsA {

     @Bean
      @Qualifier("ClasA")
      public String getSomething(){
         return "somethingA";
     }
}


@Configuration
public class ClsB {

     @Bean
      @Qualifier("ClsB")
      public String getSomething(){
         return "somethingB";
     }
}

两者都具有相同的方法名称。即使限定符不同,该应用程序也不会加载,因为它仅注入一个,而在另一个注入任何地方,如果失败并出现noBeanDefinition异常,那么就用ClsB bean限定符说。

当我使用不同的方法名称时,所有内容都会加载“笨拙”。

这种行为正常吗?为什么这些弹簧具有不同的限定符就不能弹簧加载呢?

2 个答案:

答案 0 :(得分:0)

@Qualifier批注应该在resolve ambiguity的注入点使用,用于注入哪个bean。但是在示例中,您在Bean声明站点使用它。在声明站点,可以通过在@Bean批注中指定每个bean的名称。因此,如果您使用相同的名称保留方法,则有效示例如下:

@Configuration
public class ClsA {
    @Bean("ClasA")
    public String getSomething() {
        return "somethingA";
    }
}

@Configuration
public class ClsB {
    @Bean("ClasB")
    public String getSomething() {
        return "somethingB";
    }
}

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {ClsB.class, ClsA.class})
public class ClsTest {
    @Autowired
    @Qualifier("ClasA") //this is the place where @Qualifier can be used
    String smthA;

    @Autowired
    @Qualifier("ClasB")
    String smthB;

    @Test
    public void test() {
        System.out.println(smthA);
        System.out.println(smthB);
    }
}

输出:

somethingA
somethingB

答案 1 :(得分:0)

1.自定义 Bean 命名

每个 bean 名称必须是唯一的。

@Configuration
public class ClsA {

    @Bean("clasAText")
    public String getSomething() {
        return "somethingA";
    }
}
@Configuration
public class ClsB {

    @Bean("clsBText")
    public String getSomething() {
        return "somethingB";
    }
}

2. (可选)添加限定符元数据

@Configuration
public class ClsA {

    @Bean("clasAText")
    @Qualifier("clsA")
    public String getSomething() {
        return "somethingA";
    }
}
@Configuration
public class ClsB {

    @Bean("clsBText")
    @Qualifier("clsB")
    public String getSomething() {
        return "somethingB";
    }
}

3-1。按名称注入

@Component
public class MyComponent {

    @Resource(name = "clasAText")
    private String text;

    // ...
}

Note

<块引用>

如果您打算通过名称来表达注解驱动的注入,请不要主要使用 @Autowired (snip)。而是使用 JSR-250 @Resource 注释

3-2。通过限定符注入

如果添加了限定符,则可以使用这些限定符。

@Component
public class MyComponent {

    @Autowired
    @Qualifier("clsA")
    private String text;

    // ...
}

This answer 是一种后备行为。名称和限定符是不同的。

<块引用>

对于回退匹配,bean 名称被视为默认限定符值。