Spring ServiceLocator oder reines Fabrikmuster?

99% meiner Abhängigkeit wird mit dem DI-Muster über die @Autowired Spring-Annotation verwaltet.

Trotzdem kann ich in einem bestimmten Szenario nicht bestimmen, welche Implementierung bis zur Laufzeit verwendet werden soll.

Der bekannteste Fall ist die mehrfache Implementierung von Parsern.

Die erste Lösung ist die Verwendung mehrerer @Autowired (hässlicher Modus)

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;

    ...     
}

Aber wenn ich eine große Anzahl von Implementierungen habe, kann das nicht akzeptabel sein.

Die zweite Lösung ist der ServiceLocator von Spring

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");
    }
}

Diese Vorgehensweise erscheint mir aber als richtig, verglichen mit der dritten Lösung?

Die dritte Lösung besteht darin, ein reines Fabrikmuster zu verwenden und es zu injizieren.

@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");
    }
}

Wenn Sie Pro / Contra für die vorherigen Lösungen oder eine noch bessere Lösung für mein Problem haben?

PS: Es ist Pseudo-Code, ich kann einige kleine Dinge verpassen :)

Antworten auf die Frage(2)

Ihre Antwort auf die Frage