0

所以基本上,我有一种情况,我想将原始类型注入一个类(即一个字符串和一个整数)。您可以将应用程序的 URL 和端口号视为示例输入。我有三个组件:

现在说我有一堂课,它确实接受了这些参数:

public class PrimitiveParamsDIExample {

  private String a;
  private Integer b;

  public PrimitiveParamsDIExample(String a, Integer b) {
    this.a = a;
    this.b = b;
  }
}

所以我的问题很简单。我如何注入ab上课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()打印变量abin的方法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。我没有正确连接什么?

谢谢!

4

1 回答 1

2

有两种方法可以做到这一点,但一种还没有记录(虽然它是可用的......我想我需要再次处理文档......)

我将在这里通过第一种方式。

基本上,您可以使用 HK2 Factory

通常,当您开始像这样生成字符串和整数以及长整数和标量时,您会对它们进行限定,所以让我们从两个限定符开始:

@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

于 2015-02-20T10:58:30.867 回答