Dependency injection 使用HK2进行基元类型的依赖项注入(在运行时决定)
因此,基本上,我有一种情况,我想将基元类型注入到一个类中(即,一个字符串和一个整数)。您可以将应用程序的URL和端口号作为示例输入。我有三个部分: 现在假设我有一个类,它接受这些参数:Dependency injection 使用HK2进行基元类型的依赖项注入(在运行时决定),dependency-injection,primitive-types,hk2,Dependency Injection,Primitive Types,Hk2,因此,基本上,我有一种情况,我想将基元类型注入到一个类中(即,一个字符串和一个整数)。您可以将应用程序的URL和端口号作为示例输入。我有三个部分: 现在假设我有一个类,它接受这些参数: public class PrimitiveParamsDIExample { private String a; private Integer b; public PrimitiveParamsDIExample(String a, Integer b) { this.a = a;
public class PrimitiveParamsDIExample {
private String a;
private Integer b;
public PrimitiveParamsDIExample(String a, Integer b) {
this.a = a;
this.b = b;
}
}
所以我的问题很简单。如何将a
和b
注入类primitiveparamsdiesample
一般来说,这也是询问如何注入在运行时决定的参数。如果我有上面的a和b,从STDIN或输入文件读取,它们显然会因运行而异
更重要的是,我如何在HK2框架内完成上述工作
编辑[02/23/15]:@jwells131313,我尝试了你的想法,但我得到了以下错误(这一个用于字符串参数;类似于int):
我的课程设置和你的答案一模一样。我还重写了toString()
方法,在PrimitiveParamsDIExample
中打印变量a
和b
。然后,我在我的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());
}
}
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);
}
}
}
其中,HK2设置如下:
@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());
}
}
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);
}
}
}
因此,在某个地方,接线混乱,我得到了一个不满意的例外。我没有正确连接的是什么
谢谢 有两种方法可以做到这一点,但其中一种还没有文档化(尽管它是可用的……我想我需要再次编写文档……) 我要走第一条路 基本上,你可以使用HK2 通常,当您开始生成字符串、整数、long和标量时,您需要对它们进行限定,因此让我们从两个限定符开始:
@Retention(RUNTIME)
@Target( { TYPE, METHOD, FIELD, PARAMETER })
@javax.inject.Qualifier
public @interface A {}
及
然后写下你的工厂:
@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...
}
}
注意我把整数改为int,好吧。。。就因为我能。您也可以以相同的方式使用字段注入或方法注入。这里是字段注入,方法注入是读者的练习:
public class PrimitiveParamsDIExample {
@Inject @A
private String a;
@Inject @B
private int b;
public PrimitiveParamsDIExample() {
}
}
有几种方法可以约束工厂
在活页夹中:
使用自动类分析:
活页夹外的EDSL:谢谢您的解释!下面的代码示例给出了一个很好的答案。我要去装订厂。今晚我也会测试一下这个想法,然后再继续。不过,作为一个补充:你不认为它有很多代码只用于阅读简单的原语吗?同意StringAFactory和IntegerFactory可以重复使用。但我可能会开发新的方法,在一个类一个类的基础上处理我的字符串和整数。这意味着我必须编写尽可能多的工厂来处理ctor输入基元类型。我同意,如果有很多值要读取,这种方法就无法扩展。因此,您可能希望使用目前正在开发但尚未准备就绪的持久性工具。我根据您的想法使用测试编辑了我的答案。你看了之后告诉我。
public class PrimitiveParamsDIExample {
private String a;
private int b;
@Inject
public PrimitiveParamsDIExample(@A String a, @B int b) {
this.a = a;
this.b = b;
}
}
public class PrimitiveParamsDIExample {
@Inject @A
private String a;
@Inject @B
private int b;
public PrimitiveParamsDIExample() {
}
}