如何为合格和范围的CDI bean创建通用生产者?

时间:2016-05-25 17:35:06

标签: java java-ee cdi

我正在尝试执行以下操作:

@Qualifier
@Retention(RUNTIME)
@Target({ PARAMETER, FIELD, METHOD, TYPE })
public @interface ForQueueName{
    String value();
}

public class JmsSenderProducer {
    @Produces
    @Any
    @ApplicationScoped
    public JmsSender createJmsSender(InjectionPoint ip) {
        ForQueueName annotation = ip.getAnnotated().getAnnotation(ForQueueName.class);
        return new JmsSender(annotation.value());
    }
}

// Somewhere else
@Inject
@ForQueueName("java:/jms/queue/my.queue.name")
JmsSender myQueueSender;

当然这不起作用,因为

  1. @Any不能替代任何合格的@ForQueueName
  2. 生成InjectionPoint bean时无法使用
  3. @ApplicationScoped
  4. 我知道我可以通过这种方式使用非绑定限定符创建@Dependent范围内的bean。但在我的情况下,我实际上需要一个非依赖范围的bean。

    有可能是预期的吗?如果没有,有什么特别的原因吗?

    干杯,蒂尔曼

    编辑:修改了从@Default@Dependent

    的范围名称

1 个答案:

答案 0 :(得分:0)

首先,您应该考虑在应用中使用JMSContext。它是一个JMS 2.0功能,具有更清晰的API。

其次,您的生产者方法应使用ForQueueName进行注释。为了实现这一点,value() ForQueueName属性需要标记为@Nonbinding。这告诉CDI容器在查找生产者时不应该考虑该值。

@Qualifier
@Retention(RUNTIME)
@Target({ PARAMETER, FIELD, METHOD, TYPE })
public @interface ForQueueName{
    @Nonbinding String value();
}

public class JmsSenderProducer {
    @Produces
    @ForQueueName("")
    @Dependent // must be dependent to interrogate the injection point
    public JmsSender createJmsSender(InjectionPoint ip) {
        ForQueueName annotation = ip.getAnnotated().getAnnotation(ForQueueName.class);
        return new JmsSender(annotation.value());
    }
}

// Somewhere else
@Inject
@ForQueueName("java:/jms/queue/my.queue.name")
JmsSender myQueueSender;