【问题标题】:Spring @Qualifier strange behaviour with setter injection带有setter注入的Spring @Qualifier奇怪行为
【发布时间】:2022-01-30 10:41:56
【问题描述】:

我遇到了一个有一些奇怪的@Qualifier 行为的代码。这不是我所期望的。

让我们考虑以下代码sn-p:

@SpringBootApplication
class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

    @Bean
    Foo foo1() {
        return new Foo("foo1");
    }

    @Bean
    Foo foo2() {
        return new Foo("foo2");
    }

    static class Foo {
        private final String name;

        public Foo(String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }
    }

    @Component
    static class Bar {
        private Foo fooOne;
        private Foo fooTwo;

        @Autowired
        @Qualifier("foo3")
        void setFoo(Foo foo1, Foo foo2) {
            this.fooOne = foo1;
            this.fooTwo = foo2;
        }

        @PostConstruct
        void printFoo() {
            System.out.println(fooOne.getName() + fooTwo.getName());
        }
    }
}

上面的代码不起作用,因为没有名为foo3Foo bean。这正是我所期望的。现在让我们更改Foo 类定义以包含@Qualifier

    @Qualifier("foo3")
    static class Foo {
    // remaining code not changed..

随着这一变化,Bar::setFoo 方法上的 @Qualifier 似乎被忽略了,foo1foo2 实例被注入。上下文中不存在 ID 为 foo3 的 bean。我很难理解这里应用的机制。谁能解释一下?

【问题讨论】:

    标签: java spring spring-boot dependency-injection


    【解决方案1】:

    通过将限定符放在类 Foo 上:

        @Qualifier("foo3")
        static class Foo {
            ...
        }
    

    每个实例化为类Foo 的bean 都将具有给定的限定符。你是正确的,这不是具有 id foo3 的单个 bean,但是存在两个具有 限定符 foo3 的 bean。

    有关该主题的更多信息可以找到here

    要注入两个 bean,请删除静态类上的限定符并在两个参数上添加一个限定符:

      @Autowired
      void setFoo(@Qualifier("foo1") Foo foo1, @Qualifier("foo2") Foo foo2) {
    

    要在应用程序上下文中使用 bean,我建议注入应用程序上下文并检索 bean 以检查它们。例如:

    
    @SpringBootApplication
    class DemoApplication {
    
        @Autowired
        ApplicationContext context
    
        @PostConstruct
        public void init() {
          
           // Beans by qualifier
           BeanFactoryAnnotationUtils.qualifiedBeanOfType(context.getBeanFactory(), YourClass.class, "foo3");
        }
    
    ... 
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-25
      • 1970-01-01
      • 2014-04-23
      • 2020-02-14
      • 2017-04-23
      • 2022-09-29
      相关资源
      最近更新 更多