使用@Qualifier 注释将所有实现自动装配到工厂中,然后从工厂返回您需要的服务类。
public class MyService {
private void doStuff();
}
我的 Windows 服务:
@Service("myWindowsService")
public class MyWindowsService implements MyService {
@Override
private void doStuff() {
//Windows specific stuff happens here.
}
}
我的 Mac 服务:
@Service("myMacService")
public class MyMacService implements MyService {
@Override
private void doStuff() {
//Mac specific stuff happens here
}
}
我的工厂:
@Component
public class MyFactory {
@Autowired
@Qualifier("myWindowsService")
private MyService windowsService;
@Autowired
@Qualifier("myMacService")
private MyService macService;
public MyService getService(String serviceNeeded){
//This logic is ugly
if(serviceNeeded == "Windows"){
return windowsService;
} else {
return macService;
}
}
}
如果你想变得非常棘手,你可以使用枚举来存储你的实现类类型,然后使用枚举值来选择你想要返回的实现。
public enum ServiceStore {
MAC("myMacService", MyMacService.class),
WINDOWS("myWindowsService", MyWindowsService.class);
private String serviceName;
private Class<?> clazz;
private static final Map<Class<?>, ServiceStore> mapOfClassTypes = new HashMap<Class<?>, ServiceStore>();
static {
//This little bit of black magic, basically sets up your
//static map and allows you to get an enum value based on a classtype
ServiceStore[] namesArray = ServiceStore.values();
for(ServiceStore name : namesArray){
mapOfClassTypes.put(name.getClassType, name);
}
}
private ServiceStore(String serviceName, Class<?> clazz){
this.serviceName = serviceName;
this.clazz = clazz;
}
public String getServiceBeanName() {
return serviceName;
}
public static <T> ServiceStore getOrdinalFromValue(Class<?> clazz) {
return mapOfClassTypes.get(clazz);
}
}
然后您的工厂可以利用应用程序上下文并将实例拉入它自己的地图中。当您添加一个新的服务类时,只需在枚举中添加另一个条目,这就是您所要做的。
public class ServiceFactory implements ApplicationContextAware {
private final Map<String, MyService> myServices = new Hashmap<String, MyService>();
public MyService getInstance(Class<?> clazz) {
return myServices.get(ServiceStore.getOrdinalFromValue(clazz).getServiceName());
}
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
myServices.putAll(applicationContext.getBeansofType(MyService.class));
}
}
现在您只需将所需的类类型传递给工厂,它就会为您提供所需的实例。非常有帮助,特别是如果您想使服务通用。