Google Guice 工厂自动装配
Google Guice Autowiring for Factory
请解释在以下场景中使用 Google-Guice 自动连接的正确方法,其中工厂 used.I 我正在使用 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 resolver.Also 这段代码是 API 的一部分,它将继续接收请求并处理 it.But 然后它必须为它收到的每个请求调用 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));
}
}
此 class 充当您的 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
}
});
我在单例中将类型绑定到它的提供者。这意味着在整个应用程序中只会使用该提供程序的 1 个实例。
或者,您也可以执行以下两个选项之一:
绑定模块中的转换器。本质上是把所有的创建代码放到guice中的一个模块中,然后将创建的Transformer单例绑定。
创建提供程序方法。这只是 Guice 模块中的一个带注释的方法,它将 return 为您提供一个 Transformer。
它们基本上都解决了同一个问题:在您的应用程序中准备好 XMLTransformer 的实例以进行注入。
我希望这就是您要找的,
阿图尔
请解释在以下场景中使用 Google-Guice 自动连接的正确方法,其中工厂 used.I 我正在使用 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 resolver.Also 这段代码是 API 的一部分,它将继续接收请求并处理 it.But 然后它必须为它收到的每个请求调用 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));
}
}
此 class 充当您的 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
}
});
我在单例中将类型绑定到它的提供者。这意味着在整个应用程序中只会使用该提供程序的 1 个实例。
或者,您也可以执行以下两个选项之一:
绑定模块中的转换器。本质上是把所有的创建代码放到guice中的一个模块中,然后将创建的Transformer单例绑定。
创建提供程序方法。这只是 Guice 模块中的一个带注释的方法,它将 return 为您提供一个 Transformer。
它们基本上都解决了同一个问题:在您的应用程序中准备好 XMLTransformer 的实例以进行注入。
我希望这就是您要找的,
阿图尔