所以基本上,我有一种情况,我想将原始类型注入一个类(即一个字符串和一个整数)。您可以将应用程序的URL和端口号视为示例输入。我有三个组成部分:
现在说我有一个班级,它确实考虑了这些参数:
public class PrimitiveParamsDIExample {
private String a;
private Integer b;
public PrimitiveParamsDIExample(String a, Integer b) {
this.a = a;
this.b = b;
}
}
所以我的问题很简单。如何将a
和b
注入课程PrimitiveParamsDIExample
?
通常,这也是询问如何注入在运行时决定的参数。如果我有上面的a和b,从STDIN或输入文件中读取,它们显然会在不同的运行中运行。
此外,我如何在HK2框架内完成上述工作?
编辑[02/23/15] :@ jwells131313,我尝试了你的想法,但我收到了以下错误(这个用于String参数;类似于int) :
org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at Injectee(requiredType=String,parent=PrimitiveParamsDIExample,qualifiers
我完全按照你的答案设置课程。我还覆盖了toString()
方法,以在a
中打印变量b
和PrimitiveParamsDIExample
。然后,我在Hk2Module类中添加了以下内容:
public class Hk2Module extends AbstractBinder {
private Properties properties;
public Hk2Module(Properties properties){
this.properties = properties;
}
@Override
protected void configure() {
bindFactory(StringAFactory.class).to(String.class).in(RequestScoped.class);
bindFactory(IntegerBFactory.class).to(Integer.class).in(RequestScoped.class);
bind(PrimitiveParamsDIExample.class).to(PrimitiveParamsDIExample.class).in(Singleton.class);
}
}
现在,我创建了一个测试类,如下所示:
@RunWith(JUnit4.class)
public class TestPrimitiveParamsDIExample extends Hk2Setup {
private PrimitiveParamsDIExample example;
@Before
public void setup() throws IOException {
super.setupHk2();
//example = new PrimitiveParamsDIExample();
example = serviceLocator.getService(PrimitiveParamsDIExample.class);
}
@Test
public void testPrimitiveParamsDI() {
System.out.println(example.toString());
}
}
其中,Hk2Setup如下:
public class Hk2Setup extends TestCase{
// the name of the resource containing the default configuration properties
private static final String DEFAULT_PROPERTIES = "defaults.properties";
protected Properties config = null;
protected ServiceLocator serviceLocator;
public void setupHk2() throws IOException{
config = new Properties();
Reader defaults = Resources.asCharSource(Resources.getResource(DEFAULT_PROPERTIES), Charsets.UTF_8).openBufferedStream();
load(config, defaults);
ApplicationHandler handler = new ApplicationHandler(new MyMainApplication(config));
final ServiceLocator locator = handler.getServiceLocator();
serviceLocator = locator;
}
private static void load(Properties p, Reader r) throws IOException {
try {
p.load(r);
} finally {
Closeables.close(r, false);
}
}
}
所以在某个地方,为了得到一个UnsatisfiedDependencyException,连线很乱。我没有正确连接什么?
谢谢!
答案 0 :(得分:2)
有两种方法可以做到这一点,但有一种方法尚未记录(虽然它可用......我想我需要再次处理文档......)
我将在这里通过第一种方式。
基本上,您可以使用HK2 Factory。
通常当你开始生成字符串和整数以及像这样的long和scalars时,你可以限定它们,所以让我们从两个限定符开始:
@Retention(RUNTIME)
@Target( { TYPE, METHOD, FIELD, PARAMETER })
@javax.inject.Qualifier
public @interface A {}
和
@Retention(RUNTIME)
@Target( { TYPE, METHOD, FIELD, PARAMETER })
@javax.inject.Qualifier
public @interface B {}
然后写你的工厂:
@Singleton // or whatever scope you want
public class StringAFactory implements Factory<String> {
@PerLookup // or whatever scope, maybe this checks the timestamp?
@A // Your qualifier
public String provide() {
// Write your code to get your value...
return whatever;
}
public void dispose(String instance) {
// Probably do nothing...
}
}
和整数:
@Singleton // or whatever scope you want
public class IntegerBFactory implements Factory<Integer> {
@PerLookup // or whatever scope, maybe this checks the timestamp?
@B // Your qualifier
public Integer provide() {
// Write your code to get your value...
return whatever;
}
public void dispose(String instance) {
// Probably do nothing...
}
}
现在让我们重新做你原来的类来接受这些值:
public class PrimitiveParamsDIExample {
private String a;
private int b;
@Inject
public PrimitiveParamsDIExample(@A String a, @B int b) {
this.a = a;
this.b = b;
}
}
注意我将Integer改为int,好吧......因为我可以。您也可以以相同的方式使用场注入或方法注入。这里是现场注入,方法注入是读者的练习:
public class PrimitiveParamsDIExample {
@Inject @A
private String a;
@Inject @B
private int b;
public PrimitiveParamsDIExample() {
}
}
有几种方法可以绑定工厂。
在活页夹中:bindFactory
使用自动类分析:addClasses
活页夹外的EDSL:buildFactory