如何动态选择基于String的服务执行DI?

时间:2014-01-27 14:11:52

标签: java spring dependency-injection

我有一个String作为输入,基于此我想选择一个service来执行。

对于以下方法,我有一个委托者类,它使用Spring 4自动注入所有可能的服务。但是可以改善这个吗?或者这是一种委托给特定服务的好方法吗?

特别是我不知道是否注入了我可能根据此课程中的操作选择的所有服务。

class Delegator {
    public MyService findService(String action) {
        switch (action) {
            case "A": return serviceA; break;
            case "B": return serviceB; break;
            //lots of other cases
        }
        return null; 
    }

    @Autowired
    private MyService serviceA;

    @Autowired
    private MyService serviceB;
}

2 个答案:

答案 0 :(得分:2)

我想你可以有几个最简单的解决方案来创建MyService接口上的回调方法,然后你可以迭代所有MyService个实现并找出要使用哪个(即return { {1}}来自支持的指定方法)。

true

这使您可以添加class Delegator { @Autowired private List<MyService> services; public MyService findService(String action) { for (MyService service : services) { if (service.canHandle(action) ) { return service } } throw new IllegalArgumentException("Could not find service to handle: "+action); } } 实现,而无需修改MyService类。

相关/ similair解决方案可能是使用Delegator注释,而不是在@Qualifier实现上添加回调方法。您的MyService必须知道弹簧Delegator,以便您可以查找所需的bean。 ApplicationContext当然与@Qualifier方法参数中传递的匹配/相关。

action

对于class Delegator { @Autowired private BeanFactory bf; public MyService findService(String action) { return BeanFactoryAnnotationUtils.qualifiedBeanOfType(bf, MyService.class, action); } } @Service @Qualifier("foo") public MyService1 implements MyService { ... } @Service @Qualifier("bar") public MyService2 implements MyService { ... } 匹配 foo ,将返回带有action foo的bean。如果找不到匹配的实现,您将获得@Qualifier

答案 1 :(得分:2)

Spring的IoC容器意味着与域无关。您似乎有非常具体的逻辑来确定特定的MyService实例。您的服务定位器是适用于此处的模式。

或者,如果逻辑更复杂,您可以让MyService接口声明supports方法。如果他们可以支持该操作,您的类将实现此方法以返回true,否则将false。您将循环遍历所有服务并返回第一个服务以返回true。 例如

@Autowired
private List<MyService> services;

public MyService findService(String action) {
    for(MyService service : services) {
        if(service.supports(action)) {
            return service;
        }
    }
    return null; // or whatever is appropriate
}