2016-09-15 61 views
3

請解釋在使用工廠的以下場景中使用Google-Guice自動連線的正確方法。我正在使用XML工廠進行XSLT處理。Google Guice爲工廠自動裝配

StringWriter strWriter = new StringWriter(); 
System.setProperty("javax.xml.transform.TransformerFactory", 
       "net.sf.saxon.TransformerFactoryImpl"); 
TransformerFactory xmlTransformerFactory = TransformerFactory.newInstance(); 
CustomUriResolver out = new CustomUriResolver(new HashMap<String, StringWriter>()); 
xmlTransformerFactory.setAttribute("http://saxon.sf.net/feature/outputURIResolver", out); 
Transformer xmlTransfomer = xmlTransformerFactory.newTransformer(new StreamSource("src/main/resources/test.xslt")); 
xmlTransfomer.transform(new StreamSource(new StringReader(xml)), new StreamResult(strWriter)); 
System.out.println(out.getResults().size()); 
for(Map.Entry resultEntry : out.getResults().entrySet()){ 
    System.out.println(resultEntry.getValue()); 
}; 

我應該有自動線變壓器廠,這需要定製URI resolver.Also這段代碼是API將繼續接受請求並處理它。但是那麼它必須調用newTransformer的一部分()爲它收到的每一個請求。

+0

你需要一個新的變壓器每次還是要變壓器可用通過吉斯在整個應用程序中的單身? – pandaadb

+0

我需要它作爲單身..我可以使用相同的實例所有請求 –

回答

1

做到這一點的方法是讓Guice簡單地處理你的依賴。你如何創建你的依賴關係取決於你 - guice並不在意(除非你必須使用攔截器,在那裏你需要爲你創建依賴關係)

對於這種情況,我將使用提供者來注入我的依賴關係。你會想要提取所有的創建邏輯,所以它會被執行一次來存儲你的轉換器,然後在任何地方注入轉換器。我使用提供者的原因是我可以注入更多的依賴關係(你可以做通過註釋的方法,提供我相信)相同

見這個例子:

public class TransformerProvider implements Provider<Transformer> { 

     @Inject 
     @Named("output.uri.resolver") 
     String outputUriResolver; 

     @Inject 
     @Named("xslt.location") 
     String xsltLocation; 

     Transformer instance = null; 

     @Override 
     public Transformer get() { 
      if(instance == null) { 
       try { 
        instance = create(); 
       } catch (TransformerConfigurationException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } 
      return instance; 
     } 

     private Transformer create() throws TransformerConfigurationException { 
      System.setProperty("javax.xml.transform.TransformerFactory", 
          "net.sf.saxon.TransformerFactoryImpl"); 
      TransformerFactory xmlTransformerFactory = TransformerFactory.newInstance(); 
      CustomUriResolver out = new CustomUriResolver(new HashMap<String, StringWriter>()); 
      xmlTransformerFactory.setAttribute(outputUriResolver, out); 
      return xmlTransformerFactory.newTransformer(new StreamSource(xsltLocation)); 
     } 
    } 

這個班充當您的Transformer的提供者。它在第一次需要時啓動它並將爲您存儲實例。或者,你也可以在構造函數中構造它。

我注入了2個常見屬性(uri resolver和xslt的位置)。後者至少可能使測試應用程序更容易(只需將不同的xslt注入提供程序來測試它)?

然後,我需要讓吉斯知道它給它綁定任何模塊中,可以使用它:

Injector i = Guice.createInjector(new AbstractModule() { 
      @Override 
      protected void configure() { 
       bind(Transformer.class).toProvider(TransformerProvider.class).in(Singleton.class); // bind factory 
      } 
     }); 

我在一個單獨的類型綁定到其供應商。這意味着在整個應用程序中只會使用該提供程序的一個實例。

或者你可以做任何的那些2個選項,以及:

  1. 綁定你的模塊中的變壓器。基本上把所有的創建代碼放到一個guice模塊中,然後把創建的Transformer作爲一個單例綁定。

  2. 創建提供者方法。這只是Guice模塊中的一個註釋方法,它將爲您返回一個Transformer。

所有這些都基本上解決了同樣的問題:在應用程序中準備好用於注入的XMLTransformer實例。

我希望這是你在找什麼,

阿圖爾

+0

對不起,遲到的迴應..這很好.. ..如果我需要用於uriresolver和xslt位置的不同的變量的多個變量的實例 –

+0

在這種情況下,您將使用輔助注入並在創建之前將您的位置和解析器提供給工廠。然後,您可以根據這些值緩存變壓器,因此您不必一遍又一遍地創建它們。你可以在這裏閱讀輔助注射:https://github.com/google/guice/wiki/AssistedInject – pandaadb