2013-09-06 9 views
9

私の依存関係の99%は@Autowired Springアノテーションを使用したDIパターンで管理しています。Spring ServiceLocatorまたは純粋な工場パターン?

しかし、特定のシナリオでは、実行時まで使用する実装を判断できません。

最もよく知られているのは、パーサーの複数の実装です。

第1の解決策は、複数の@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; 

    ...  
} 

しかし、私は許容できないとすることができる実装の数が多い場合。

第二の溶液は、春

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

からのServiceLocatorを使用することで行うため、この方法は、右のように思えるが、第三の溶液と比較して?

第3の解決策は、純粋な工場パターンを使用して注入することです。

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

あなたは私の問題のために、以前のソリューション、またはより良い解決のための/詐欺プロ持っている場合は?

PSは:それは、私はいくつかの小さなものを見逃す可能性:)

答えて

8

リスト注入を使用することができますオプションとして擬似コードです:

さらに良い
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; 
    } 

} 

、あなたはpaser検出コードを簡素化するためにParser.isCompatibleWith(SomeInput input)メソッドを追加することができます。

+0

ハム@Autowiredリストにはありますか?私はそれがXMLを使用する可能性があることを知っているが、私は注釈について聞いたことがない。ドキュメントリンクがありますか? – Kakawait

+1

はい、可能です。私は実際に私の現在のプロジェクトでこのアプローチを使用しています。 [型付きのコレクションの例に移動](http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/beans.html#beans-autowired-annotation)。 –

+0

上記で提案されたアプローチのわずかな変更は、パーサータイプのMAPコレクションを使用することです。このようにして、タイプの名前であるマップキーを使用して、一定の時間内にルックアップを実行できます。パーサーサービスを検索するたびに、FORループを回避します。 – Kingz

5

以下は、サービスロケータクラスの例です。これは、サービスレジストリから指定されたIDのサービスを返します。レジストリは、示されているようにautowiredな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); 
} 
関連する問題