这与Pass Parameter to Instance of @Inject Bean
中提到的问题相关但我的实施需要一些不同的方法。
为了在注入时传递参数,可以创建自定义限定符,如:
@Qualifier
@Target({ TYPE, METHOD, PARAMETER, FIELD })
@Retention(RUNTIME)
@Documented
public @interface SendInject{
@Nonbinding
int value() default 0; // int value will be store here
}
要注入的类需要使用@SendInject
注释为:
@SendInject
public class Receiver{
int in;
private int extractValue(InjectionPoint ip) {
for (Annotation annotation : ip.getQualifiers()) {
if (annotation.annotationType().equals(SendInject.class))
return ((SendInject) annotation).value();
}
throw new IllegalStateException("No @Initialized on InjectionPoint");
}
@Inject
public Receiver(InjectionPoint ip) {
this.in= extractValue(ip);
}
..........
}
注入Receiver
时,所有成员都需要使用自定义限定符@SendInject
。像:
public class Sender{
@Inject
@SendInject(9)
Receiver receiver;
..................
}
我每次注入Receiver时都不想使用@SendInject
,因为没有必要在我的实现的几个点传递参数。是否有任何方法可以在注入Recevier
时自定义自定义限定符,以便只有在需要传递某个参数时才能使用它?
我尝试这样做,但在部署我的组件时获得Ambiguous dependency error
。
答案 0 :(得分:2)
这意味着你想拥有两种类型的接收器(一种是@SendInject
,一种是non-@SendInject
)。您应该让CDI知道如何创建它们。
例如,您可以使用producer方法创建@SendInject
Receiver并使用bean的构造函数来创建non-@SendInject
Receiver:
public class Receiver {
int in;
public Receiver() {
}
public Receiver(int in) {
this.in = in;
}
private static int extractValue(InjectionPoint ip) {
for (Annotation annotation : ip.getQualifiers()) {
if (annotation.annotationType().equals(SendInject.class))
return ((SendInject) annotation).value();
}
}
@Produces
@SendInject
public static Receiver createSendInjectReceiver(InjectionPoint ip) {
int in = extractValue(ip);
return new Receiver(in);
}
}
并像往常一样注入不同的Receiver
类型:
public class Client{
/************************************
This receiver is created by constructor
**************************************/
@Inject
Receiver receiver1;
/************************************
This receiver is created by producer method
**************************************/
@Inject
@SendInject(999)
Receiver receiver2;
}