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

Passing parameter while injecting and retrieving using InjectionPoint

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

要注入的class需要注解@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

这意味着您需要两种类型的 Receiver(一种是 @SendInject,一种是 non-@SendInject)。你应该让 CDI 知道如何创建它们。

例如,您可以使用生产者方法创建 @SendInjectReceiver 并使用 bean 的构造函数创建 non-@SendInjectReceiver :

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