Kak*_*ait 12 java spring dependency-injection service-locator
99%的我的依赖是通过@Autowired Spring注释用DI模式管理的.
然而,在特定情况下,我无法确定在运行时使用哪个实现.
最着名的情况是解析器的多重实现.
第一个解决方案是使用多个@Autowired(丑陋模式)
Interface Parser {
<T> T parse();
}
@Component("JsonParser")
class JsonParser implements Parser {
...
}
@Component("XmlParser")
class XmlParser implements Parser {
...
}
class MyService {
@Autowired
@Qualifier("XmlParser")
Parser xmlParser;
@Autowired
@Qualifier("JsonParser")
Parser jsonParser;
...
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我有大量的实现,那是不可接受的.
第二个解决方案是使用Spring的ServiceLocator
interface ParserServiceLocatorFactory {
public Parser getParser(String parserName);
}
interface Parser {
<T> T parse();
}
@Component("JsonParser")
class JsonParser implements Parser {
...
}
@Component("XmlParser")
class XmlParser implements Parser {
...
}
class MyService {
@Autowired
ServiceFactory parserServiceLocatorFactory;
void exampleMethod() {
Parser xmlParser = parserServiceLocatorFactory.getParser("XmlParser");
}
}
Run Code Online (Sandbox Code Playgroud)
这种方式对我来说似乎是正确的,但与第三种解决方案相比较?
第三种解决方案是使用纯工厂模式并注入它.
@Component
public ParserFactory {
Parser getParser(String parserName) {
...
}
}
interface Parser {
<T> T parse();
}
@Component("JsonParser")
class JsonParser implements Parser {
...
}
@Component("XmlParser")
class XmlParser implements Parser {
...
}
class MyService {
@Autowired
ParserFactory parserFactory
void exampleMethod() {
Parser xmlParser = parserFactory.getParser("XmlParser");
}
}
Run Code Online (Sandbox Code Playgroud)
如果你有以前解决方案的pro/con,或者甚至更好地解决我的问题?
PS:这是伪代码我可能会错过一些小东西:)
Mak*_*das 10
作为选项,您可以使用列表注入:
public class SomeService {
@Autowired
private List<Parser> parsers;
public doSomethingWithParser(...) {
...
Parser parser = getParser(JsonParser.class);
parser.parse(...);
...
}
private Parser getParser(Class<Parser> targetClass) {
Parser result = null;
for(Parser parser : parsers) {
if(parser.getClass().equals(targetClass)){
result = parser;
}
}
return transformer;
}
}
Run Code Online (Sandbox Code Playgroud)
更好的是,您可以添加Parser.isCompatibleWith(SomeInput input)
方法来简化paser检测代码.
下面是服务定位器类的示例.这将从服务注册表返回给定ID的服务.注册表是MAP,如图所示自动装配.这是生产系统的一个工作示例:
@Service
public class MyServiceLocator {
@Autowired
private Map<String, MyService> myServiceRegistry;
/**
* Service locator to find the right Domain service to interact with the requested data store
*
* @param serviceID
* @return
*/
public MyService locateServiceFor(String serviceID) {
//Using the Given string 'serviceID' as key, lookup the service from the Registry
return myServiceRegistry.get(serviceID);
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
9897 次 |
最近记录: |