BeanFacotry和相同类型的Bean

时间:2018-02-08 20:34:03

标签: java spring

我有两个实现我的服务接口的服务,我想在运行时根据某些规则选择正确的服务,例如:

public interface Service { public String doSomething(String param); }

@Component("serviceAimpl") 
public class ServiceAImpl implements Service{ 
    public String doSomething(String param){ 
        return param + "A";
    }
}

@Component("serviceBimpl") 
public class ServiceBImpl implements Service{ 
    public String doSomething(String param){
        return param;
    }
}

当param以“1”开头并且必须使用ServiceBImpl时必须使用ServiceAImpl,否则,有什么方法可以执行上述操作:

@Component public class ServiceImpl implements Service {
    @Autowired private Map<String, Service> services;
    public String doSomething(String param) {
         if(param.startsWith("1")
             return services.get("serviceAimpl").doSomething(param);
         else
             return services.get("serviceBimpl").doSomething(param);
    }
}

这样工厂的类型与bean本身的类型相同,因此不需要创建新类型来获取bean然后使用bean。这在春天有效吗?是否有任何方法或约定来做上面描述的事情(忽略我只在那里连接字符串的事实)?

2 个答案:

答案 0 :(得分:1)

我认为您可以使用两个单独的@Autowired属性,如下所示:

@Service("serviceAimpl") 
public class ServiceAImpl implements Service{ 
    public String doSomething(String param){ 
        return param + "A";
    }
}

@Service("serviceBimpl") 
public class ServiceBImpl implements Service{ 
    public String doSomething(String param){
        return param;
    }
}
@Service("mainService")
public class ServiceImpl {
    @Autowired
    private ServiceAImpl serviceAimpl;
    @Autowired
    private ServiceBImpl serviceBimpl;

    public String doSomething(String param) {
         if(param.startsWith("1")
             return this.serviceAimpl.doSomething(param);
         else
             return this.serviceBimpl.doSomething(param);
    }
}

编辑:如果您想要自动装配地图,列表,这里的一些属性集是一个有趣的article

答案 1 :(得分:1)

Nikol给出了一个很好的解决方案,我也会这样做。但是不完全了解你的要求,所以你也可能对以下选项感兴趣。

From spring docs

  

只要预期的键类型为String,即使是类型化的地图也可以自动装配。 Map值将包含所需类型的所有bean,键将包含相应的bean名称:

因此可以获取bean名称和bean,并以你想要的方式使用它

@Autowired
private Map<String, Service > services;

if(somecondition)
   services.get("serviceAimpl"). doSomething();
else 
   services.get("ServiceBImpl"). doSomething()