【问题标题】:Injecting Collection of Interface Type into Method Annotated with @Bean将接口类型的集合注入到使用 @Bean 注释的方法中
【发布时间】:2020-01-31 05:13:11
【问题描述】:

使用 Spring 并给定几个实现公共接口的类,我将如何在方法级别使用 @Bean 注释来引用实现该接口的所有类?

我想检索所有实现实例,对每个实例应用一些逻辑,然后返回一个托管的 Map<String, Animal> 对象,该对象可以注入到其他类或组件中。

通用接口

public interface Animal {

   String makeNoise();

}
public interface Person {

   String getOccupation();

}

动物实现#1

public Dog implements Animal {

   @Override
   String makeNoise() {
      return "Bark! Bark!";
   }

} 

动物实现#2

public Cat implements Animal {

   @Override
   String makeNoise() {
      return "Meow! Meow!";
   }

} 

人员实施#1

public Developer implements Person {

   @Override
   public String getOccupation() {
      return "Software Engineer";
   }

}

人员实施#2

public Lawyer implements Person {

   @Override
   public String getOccupation() {
      return "Litigator";
   }

}

配置

@Configuration
public class Initialize {

   //<snip> Beans created for Developer, and Lawyer objects </snip>

   @Bean
   Map<String, Developer> getDevelopers(List<Developer> developers) { // This is fine
      return new HashMap<>(...);
   }

   @Bean
   Map<String, Lawyer> getLawyers(List<Person> people) { // Spring wires this dependency fine
      return new HashMap<>(...);
   }

   @Bean
   Map<String, Dog> getOwners(Map<String, Person> owners) { // Spring reports it cannot auto-wire this dependency
                                                            // what do I do here? 
   }

}

任何帮助将不胜感激,谢谢!

【问题讨论】:

  • 您需要一个 List&lt;Animals&gt; 类型的 Bean 在运行时出现在上下文中。只有这样才能满足你想要的bean的依赖。
  • @rdas 这真的是 Spring 的唯一方法吗?我想利用类路径的运行时扫描来自动获取实现类。
  • 最简单的方法是使用@Bean 方法来做同样的事情。
  • 看起来可能是这个问题的重复:stackoverflow.com/questions/40286047/…
  • 在你们的帮助下找到了答案,我会在回家时更新问题并提供答案。基本上利用协方差和列表来说服 Spring 将所有类/bean 连接到该列表

标签: java spring


【解决方案1】:

试试这种配置。这里唯一的一点是集合中bean的顺序是随机的,无法控制。

    @Configuration
    public class CollectionConfig {

        @Bean
        public Animal getCat() {
            return new Cat();
        }

        @Bean
        public Animal getDog() {
            return new Dog();
        }

        @Bean
        Map<String, Animals> gatherAnimals(List<Animals> animals) {
           // any code
        }
    }

这里有更多关于https://www.baeldung.com/spring-injecting-collections

【讨论】:

    【解决方案2】:

    需要利用 List 的协方差。参见下面的伪代码/代码 sn-p。

    @Configuration
    public class Initialize {
    
       //<snip> Beans created for Developer, and Lawyer objects </snip>
    
       @Bean
       Map<String, Developer> getDevelopers(List<Developer> developers) {
          return new HashMap<>(...);
       }
    
       @Bean
       Map<String, Lawyer> getLawyers(List<Person> people) {
          return new HashMap<>(...);
       }
    
       @Bean
       Map<String, Dog> getOwners(List<Map<String, ? extends Person>> owners) { // Spring will auto-wire the "owners" variable 
                                                                                // with all bean objects that match this signature 
                                                                                // (✅ Map<String, Lawyer>, ✅ Map<String, Developer> ...)
    
       }
    
    }
    
    

    资源:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-08-01
      • 1970-01-01
      • 2012-01-08
      • 1970-01-01
      • 2023-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多