我想知道如何使用Spring3注释实现简单的工厂模式。我在文档中看到,您可以创建调用工厂类并运行工厂方法的bean。我想知道是否可以只使用注释。
我有一个控制器,它当前调用
MyService myService = myServiceFactory.getMyService(test);
result = myService.checkStatus();MyService是一个具有名为checkStatus()的方法的接口。
我的工厂类看起来像这样:
@Component
public class MyServiceFactory {
public static MyService getMyService(String service) {
MyService myService;
service = service.toLowerCase();
if (service.equals("one")) {
myService = new MyServiceOne();
} else if (service.equals("two")) {
myService = new MyServiceTwo();
} else if (service.equals("three")) {
myService = new MyServiceThree();
} else {
myService = new MyServiceDefault();
}
return myService;
}
}MyServiceOne类如下所示:
@Autowired
private LocationService locationService;
public boolean checkStatus() {
//do stuff
}当我运行这段代码时,locationService变量总是空的。我认为这是因为我自己在工厂中创建对象,并且自动装配没有发生。有没有一种方法可以添加注释来使其正确工作?
谢谢
发布于 2011-06-18 03:35:04
您是对的,通过手动创建对象,您不会让Spring执行自动装配。也可以考虑使用Spring管理您的服务:
@Component
public class MyServiceFactory {
@Autowired
private MyServiceOne myServiceOne;
@Autowired
private MyServiceTwo myServiceTwo;
@Autowired
private MyServiceThree myServiceThree;
@Autowired
private MyServiceDefault myServiceDefault;
public static MyService getMyService(String service) {
service = service.toLowerCase();
if (service.equals("one")) {
return myServiceOne;
} else if (service.equals("two")) {
return myServiceTwo;
} else if (service.equals("three")) {
return myServiceThree;
} else {
return myServiceDefault;
}
}
}但我认为它的整体设计相当糟糕。拥有一个通用的MyService实现并将one/two/three字符串作为额外参数传递给checkStatus()不是更好吗?你想实现什么目标?
@Component
public class MyServiceAdapter implements MyService {
@Autowired
private MyServiceOne myServiceOne;
@Autowired
private MyServiceTwo myServiceTwo;
@Autowired
private MyServiceThree myServiceThree;
@Autowired
private MyServiceDefault myServiceDefault;
public boolean checkStatus(String service) {
service = service.toLowerCase();
if (service.equals("one")) {
return myServiceOne.checkStatus();
} else if (service.equals("two")) {
return myServiceTwo.checkStatus();
} else if (service.equals("three")) {
return myServiceThree.checkStatus();
} else {
return myServiceDefault.checkStatus();
}
}
}这仍然是糟糕的设计,因为添加新的MyService实现也需要修改MyServiceAdapter (违反SRP)。但这实际上是一个很好的起点(提示:映射和策略模式)。
发布于 2016-09-07 12:58:20
下面的方法对我很有效:
该接口由您的逻辑方法和附加标识方法组成:
public interface MyService {
String getType();
void checkStatus();
}一些实现:
@Component
public class MyServiceOne implements MyService {
@Override
public String getType() {
return "one";
}
@Override
public void checkStatus() {
// Your code
}
}
@Component
public class MyServiceTwo implements MyService {
@Override
public String getType() {
return "two";
}
@Override
public void checkStatus() {
// Your code
}
}
@Component
public class MyServiceThree implements MyService {
@Override
public String getType() {
return "three";
}
@Override
public void checkStatus() {
// Your code
}
}工厂本身如下所示:
@Service
public class MyServiceFactory {
@Autowired
private List<MyService> services;
private static final Map<String, MyService> myServiceCache = new HashMap<>();
@PostConstruct
public void initMyServiceCache() {
for(MyService service : services) {
myServiceCache.put(service.getType(), service);
}
}
public static MyService getService(String type) {
MyService service = myServiceCache.get(type);
if(service == null) throw new RuntimeException("Unknown service type: " + type);
return service;
}
}我发现这样的实现更容易,更整洁,更具可扩展性。添加新的MyService就像创建另一个实现相同接口的spring bean一样简单,而不需要在其他地方做任何更改。
发布于 2019-03-08 17:33:19
下面是DruidKuma的回答
使用自动连接的构造器对他的工厂进行少量重构:
@Service
public class MyServiceFactory {
private static final Map<String, MyService> myServiceCache = new HashMap<>();
@Autowired
private MyServiceFactory(List<MyService> services) {
for(MyService service : services) {
myServiceCache.put(service.getType(), service);
}
}
public static MyService getService(String type) {
MyService service = myServiceCache.get(type);
if(service == null) throw new RuntimeException("Unknown service type: " + type);
return service;
}
}https://stackoverflow.com/questions/6390810
复制相似问题