通过@Autowired
Spring注释,我的依赖关系的99%通过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; ... }
但是如果我有大量的实现是不能接受的.
第二个解决方案是从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"); } }
这样做对我来说似乎是对的,但与第三种解决方案相比呢?
第三个解决方案是使用纯工厂模式并注入.
@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"); } }
如果您有以前的解决方案的pro / con,或者更好地解决我的问题?
PS:这是伪码我可能会想念一些小东西:)
解决方法
作为一个选项,您可以使用列表注入:
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; } }
更好的是,您可以添加Parser.isCompatibleWith(SomeInput输入)方法来简化paser检测代码.