将参数传递给@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构造函数注入 )
我希望,我回答了这个问题。