我使用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<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
。
现在,任何人都知道我该怎么做?
我不确定你要做什么,但根据我的理解,你想用注入点注释中的数据初始化你的bean,或者在运行时通过程序化查找来初始化你的bean。你可以通过使用来做到这一点 InjectionPoint
bean中的元数据(唯一的约束是将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<Initialized> 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<MyNumber> myNumberInstance;
public MyNumber getMyNumberBeanFor(int value) {
return myNumberInstance.select(new InitializedLiteral(value)).get();
}
...
}
请记住,这只适用于 MyNumber
在依赖范围内是有意义的,因为它是在每次注入时更改初始化值的唯一方法。
我不确定你要做什么,但根据我的理解,你想用注入点注释中的数据初始化你的bean,或者在运行时通过程序化查找来初始化你的bean。你可以通过使用来做到这一点 InjectionPoint
bean中的元数据(唯一的约束是将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<Initialized> 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<MyNumber> myNumberInstance;
public MyNumber getMyNumberBeanFor(int value) {
return myNumberInstance.select(new InitializedLiteral(value)).get();
}
...
}
请记住,这只适用于 MyNumber
在依赖范围内是有意义的,因为它是在每次注入时更改初始化值的唯一方法。
根据规范,没有办法让bean有一个不简单的“不注入”构造函数( 3.1。管理豆类 , 3.9。 Bean构造函数 )。
因此,设置参数的方法是为它们设置setMethod(),将它们作为bean中的@Inject字段或使用注释@Inject注释构造函数,并使构造函数的参数可注入( 5.5.1。使用bean构造函数注入 )
我希望,我回答了这个问题。