将参数传递给@Inject Bean的实例 [英] Pass Parameter to Instance of @Inject Bean

查看:218
本文介绍了将参数传递给@Inject Bean的实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用CDI作为注入框架,但我发现它的使用有一些限制,这就是其中之一。我正在尝试使用运行时值初始化bean实例的创建。示例:

I am using CDI as injection framework, but I have found some limitations in its usage, and this is one of them. I am trying to initialize the creation of a bean instance with runtime values. Example:

@RequestScoped
public class MyNumber {
   int number;

   public MyNumber(int number) {
      this.number = number;
   }

   public String toString() {
      return "Your number is: " + number;
   }
}

public class UseNumber {
   @Inject
   Instance<MyNumber> number;

   public void doStuff() {
      int a = 8;
      MyNumber mN = number.select(a).get(); // ?? - Obviously this does not work.

      System.out.print(mN); // Should print: "Your number is: 8"
   }
}

请注意,a是示例中的常量,但实际上它是一个变量;我澄清这一点,所以你不要用 @Producer 发布一个答案,然后在 MyNumber 。

Please, notice that "a" is a constant in the example, but in practice it is a variable; I clarify this so you don't post an answer with a @Producer to inject the value then in the constructor of MyNumber.

现在,任何人都知道我该怎么做?

Now, anybody has an idea about how can I do that?

推荐答案

我不确定你要做什么,但据我所知,你想用注入点注释中的数据初始化你的bean,或者在运行时通过程序化查找来初始化你的bean。你可以通过在bean中使用 InjectionPoint 元数据来做到这一点(唯一的约束是将你的bean放在依赖范围内)

I'm not sure what you're trying to do, but from what I understand you want to initialize your bean with data in injection point annotation or at runtime thru programmatic lookup. You can do this by using InjectionPoint meta data in your bean (the only constraint will be to put your bean in dependent scope)

你可以这样做。

首先创建一个非约束值的限定符。

First create a qualifier with a non binding value.

@Qualifier
@Target({TYPE, METHOD, PARAMETER, FIELD})
@Retention(RUNTIME)
@Documented
public @interface Initialized {

    @Nonbinding int value() default 0; // int value will be store here 
}

您必须在此处添加此限定符bean并在创建时分析 InjectionPoint

You have to add this qualifier on your bean and analyze InjectionPoint at creation time.

@Initialized
public class MyNumber {
   int number;

   private int extractValue(InjectionPoint ip) {
    for (Annotation annotation : ip.getQualifiers()) {
        if (annotation.annotationType().equals(Initialized.class))
            return ((Initialized) annotation).value();
    }
    throw new IllegalStateException("No @Initialized on InjectionPoint");
  }

   @Inject
   public MyNumber(InjectionPoint ip) {
      this.number = extractValue(ip);
   }

   public String toString() {
      return "Your number is: " + number;
   }
}

您现在可以注入一个初始化的数字:

You can now inject an initialized number like this:

@Inject
@Initialized(8)
MyNumber number;

如果要在运行时决定初始化值,则必须使用编程查找:

If you want to decide the initialization value at runtime, you'll have to use programmatic lookup:

首先为`@ Initialized``创建注释文字

First create the annotation literal for `@Initialized``

public class InitializedLiteral extends AnnotationLiteral<Initialized> implements Initialized {

    private int value;

    public InitializedLiteral(int value) {
        this.value = value;
    }

    @Override
    public int value() {
        return value;
    }
}

然后你可以使用实例创建你的bean。

Then you can use Instance to create your bean.

public class ConsumingBean {

    @Inject
    @Any
    Instance<MyNumber> myNumberInstance;

    public MyNumber getMyNumberBeanFor(int value) {
     return myNumberInstance.select(new InitializedLiteral(value)).get();
    }
    ...
}

请记住这只有效如果 MyNumber 处于依赖范围内,这是有意义的,因为它是每次注入时更改初始化值的唯一方法。

Remember this works only if MyNumber is in dependent scope which makes sense because it's the only way to change initialization value at each injection.

这篇关于将参数传递给@Inject Bean的实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆