使用InjectionPoint注入和检索时传递参数

时间:2015-12-07 06:48:58

标签: java javabeans cdi inject qualifiers

这与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

1 个答案:

答案 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;
}