春季:注入实现接口的所有具体类的列表

时间:2019-11-14 21:46:25

标签: java spring spring-boot dependency-injection

我有一个@Service类,其中包含其他List类的@ServiceList基本上包含implements UniformEventsResearchApi所有服务。

作为Spring的新秀,我不确定如何让Spring允许我关注the Open-Closed Principle,从而自动将所有具体实现注入该列表。

这是不完整的UML类图:

uml class diagram

这是一些“代码”:

@Service
public class EventsResearchService {

    // todo: this should be Injected automatically
    private List<UniformEventsResearchApi> eventsResearchApis = Arrays.asList(new EventbriteApi());

// Already tried, but without success:
//
//    @Autowired
//    private List<UniformEventsResearchApi> eventsResearchApis2;
//
//    @Autowired
//    @Qualifier("EventsResearchApi")
//    public void setXList(List<UniformEventsResearchApi> apis) {
//        this.eventsResearchApis2 = apis;
//    }

}


@Service
@Qualifier("EventsResearchApi")
public interface UniformEventsResearchApi { /* ... */ }


public abstract class EventsResearchApi implements UniformEventsResearchApi { /* ... */ }


/** Any class like this one which extends EventsResearchApi should be automatically injected in the List */
public class EventbriteApi extends EventsResearchApi { /* ... */ }

1 个答案:

答案 0 :(得分:2)

实际上,这是春季的一项简单任务:

您可以像常规bean一样自动连接bean列表 在这种情况下,spring确实会找到实现该接口的所有bean并注入:

public interface SomeInterface {
}

@Component
public class SomeImpl1 implements SomeInterface {}

@Component
public class SomeImpl2 implements SomeInterface {}

@Service
public сlass SampleBean {

     @Autowired
     private List<SomeInterface> beans;
}

请注意,至少应有一种bean的实现, 否则,Spring不会允许您进行此类注射。如果您知道可能出现这种情况,可以注入Optional<List<SomeInterface>>

使用字段注入看起来很丑陋,但是您可以使用构造函数注入(无论如何还是更好)或考虑使用“ java配置”:

@Service
public class SampleBean {
   private final List<SomeInterface> beans;
   // I haven’t checked this with compiler, should work
    @Autowired // optional, if you have a single constructor, you can omit it
    public SampleBean(Optional<List<SomeInterface>> beans) {
       this.beans = beans.orElse(Collections.emptyList());   
    }
}
相关问题