Google Guice自动装配工厂

在使用工厂的以下场景中,请解释使用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());
};

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

最佳答案 这样做的方法是简单地让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));
        }
    }

此类充当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
            }
        });

我在一个单例中将Type绑定到它的提供者.这意味着在整个应用程序中只会使用该提供程序的一个实例.

或者,您也可以选择以下两个选项中的任何一个:

>将变压器绑定在模块中.基本上将所有创建代码放入guice中的模块中,然后将创建的Transformer绑定为单例.
>创建提供者方法.这只是Guice模块中的一个带注释的方法,它将为您返回一个Transformer.

所有这些都基本上解决了同样的问题:在您的应用程序中准备好一个XMLTransformer实例以进行注入.

我希望这就是你要找的东西,

阿图尔

点赞