将参数传递给@Inject Bean的实例

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

@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 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的构造函数中注入值。

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

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

你可以做这样的事情。

首先创建一个具有非绑定值的限定符。

 @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

 @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; } } 

您现在可以注入一个初始化的数字,如下所示:

 @Inject @Initialized(8) MyNumber number; 

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

首先为`@Instatedized“创建注释文字

 public class InitializedLiteral extends AnnotationLiteral implements Initialized { private int value; public InitializedLiteral(int value) { this.value = value; } @Override public int value() { return value; } } 

然后,您可以使用Instance来创建bean。

 public class ConsumingBean { @Inject @Any Instance myNumberInstance; public MyNumber getMyNumberBeanFor(int value) { return myNumberInstance.select(new InitializedLiteral(value)).get(); } ... } 

请记住,仅当MyNumber处于依赖范围内时才MyNumber ,因为它是在每次注入时更改初始化值的唯一方法。

根据规范,没有办法让bean具有不简单的“不注入”构造函数( 3.1。托管bean , 3.9。Bean构造函数 )。

因此,设置参数的方法是为它们设置setMethod(),将它们作为bean中的@Inject字段或使用注释@Inject注释构造函数,并使构造函数的参数可注入( 5.5.1) 。使用bean构造函数注入 )

我希望,我回答了这个问题。