Google Guice 工厂自动装配

Ren*_*n V 5 guice autowired

请解释在以下使用工厂的场景中使用 Google-Guice 自动连接的正确方法。我使用 XML 工厂进行 XSLT 处理。

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());
};
Run Code Online (Sandbox Code Playgroud)

我是否必须自动连接 Transformer factory ,这需要自定义 URI 解析器。此外,这段代码是 API 的一部分,它将继续接收请求并处理它。但是它必须为收到的每个请求调用 newTransformer() 。

pan*_*adb 3

做到这一点的方法就是让 Guice 为您处理依赖关系。如何创建依赖关系取决于您 - 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));
        }
    }
Run Code Online (Sandbox Code Playgroud)

此类充当 Transformer 的提供者。它会在第一次需要时启动它并为您存储实例。或者,您也可以在构造函数中构造它。

我正在注入 2 个常见属性(uri 解析器和 xslt 的位置)。后者至少可以使测试您的应用程序变得更容易(只需将不同的 xslt 注入提供程序来测试它?)。

然后我需要将它绑定到任何模块中,以便 Guice 知道它并可以使用它:

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

我将类型绑定到单例中的提供者。这意味着整个应用程序将仅使用该提供程序的 1 个实例。

或者,您也可以执行这两个选项之一:

  1. 将变压器绑定到您的模块中。本质上是将所有创建代码放入 guice 中的一个模块中,然后将创建的 Transformer 绑定为单例。

  2. 创建一个提供者方法。这只是 Guice 模块中的一个带注释的方法,它将为您返回一个 Transformer。

所有这些本质上都解决了相同的问题:在应用程序中准备好 XMLTransformer 的实例以供注入。

我希望这就是您正在寻找的

阿图尔