2013-09-06 34 views
9

99% phụ thuộc của tôi là quản lý bằng mẫu DI thông qua chú thích Spring @Autowired.Spring ServiceLocator hoặc mô hình nhà máy tinh khiết?

Tuy nhiên trong một trường hợp cụ thể, tôi không thể xác định triển khai nào sẽ được sử dụng cho đến thời gian chạy.

Trường hợp được biết nhiều nhất, là triển khai nhiều trình phân tích cú pháp.

Các giải pháp đầu tiên là sử dụng nhiều @Autowired (chế độ xấu xí)

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; 

    ...  
} 

Nhưng nếu tôi có một số lượng lớn thực hiện đó có thể là không thể chấp nhận được.

Giải pháp thứ hai là sử dụng ServiceLocator từ mùa xuân

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

Bằng cách này để làm dường chánh đáng cho tôi nhưng so với các giải pháp thứ ba?

Giải pháp thứ ba là sử dụng mẫu nhà máy thuần túy và tiêm nó.

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

Nếu bạn có giải pháp cho các giải pháp trước đó hoặc giải pháp tốt hơn cho vấn đề của mình?

PS: đó là mã giả tôi có thể bỏ lỡ một số điều nhỏ :)

Trả lời

8

Là một tùy chọn mà bạn có thể sử dụng danh sách tiêm:

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

} 

Thậm chí tốt hơn, bạn có thể thêm Parser.isCompatibleWith(SomeInput input) phương pháp để đơn giản hóa mã phát hiện paser .

+0

Hum có thể @Autowired a list? Tôi biết nó có thể sử dụng XML nhưng tôi chưa bao giờ nghe nói về chú thích. Bạn có một số liên kết doc? – Kakawait

+1

Có, điều đó là có thể. Tôi thực sự sử dụng cách tiếp cận này trong dự án hiện tại của tôi. [Đi xuống ví dụ về bộ sưu tập đã nhập] (http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/beans.html#beans-autowired-annotation). –

+0

Một sửa đổi nhỏ cho cách tiếp cận được đề xuất ở trên sẽ là sử dụng bộ sưu tập MAP của các loại trình phân tích cú pháp. Bằng cách này, bạn có thể thực hiện tra cứu trong thời gian không đổi, sử dụng khóa bản đồ là tên của loại. Nó sẽ tránh vòng lặp FOR mỗi khi bạn muốn tra cứu một dịch vụ phân tích cú pháp. – Kingz

5

Dưới đây là ví dụ về lớp trình định vị dịch vụ. Điều này trả về một dịch vụ cho ID đã cho từ sổ đăng ký dịch vụ. Việc đăng ký là một MAP được autowired như được hiển thị. Đây là ví dụ hoạt động từ hệ thống sản xuất:

@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); 
} 
Các vấn đề liên quan