【问题标题】:CDI: @Produces method is not injecting after invoking Instance with an AnnotationLiteralCDI:@Produces 方法在使用 AnnotationLiteral 调用 Instance 后未注入
【发布时间】:2013-12-06 11:45:11
【问题描述】:

我正在尝试通过 AnnotationLiteral 调用 CDI 托管 bean:

@Inject
@Any
private Instance<FacesI18nService> services;

public FacesI18nService produceFacesServiceProgrammatically(Domain domain) {    
    return services.select(new DomainQualifier(domain)).get();
}

DomainQualifier 只是一个标准的 AnnotationLiteral 实现:

public class DomainQualifier extends AnnotationLiteral<I18nResource> implements I18nResource {

    private static final long serialVersionUID = 1L;
    private final Domain domain;

    public DomainQualifier(Domain domain) {
        this.domain = domain;
    }

    @Override
    public Domain value() {
        return domain;
    }

}

问题是我确实得到了一个新的FacesI18nService,它是通过相应的@Produces 方法生成的。但是,@Inject'd 的 FacesI18nService 成员始终是 null

@Produces
@I18nResource
public FacesI18nService produceFacesService(InjectionPoint ip) {

    for (Annotation a : ip.getQualifiers()) {
        if (a instanceof I18nResource) {
            Domain domain = ((I18nResource) a).value();
            return new FacesI18nService(new I18nService(domain, databaseBundleService));
        }
    }
    throw new IllegalArgumentException("Could not find any matching qualifier");
}

那么,我在这里做错了什么?

【问题讨论】:

    标签: jakarta-ee dependency-injection cdi


    【解决方案1】:

    好吧..明白了耻辱

    为了生成 CDI 托管 bean,不应实例化返回值,而应将其作为参数传递给方法,并将此参数作为结果返回。

    @Produces
    @Dependent
    @I18nResource
    public FacesI18nService produceFacesService(InjectionPoint ip, @New FacesI18nService ret) {
    
        [...]
    
        ret.setI18nService(new I18nService(domain, databaseBundleService));
        return ret;
    }
    

    【讨论】:

    • 这当然不是真的。你@I18nResource注解的参数是@Nonbinding吗?
    • 是的,它是@Nonbinding。为什么你说这不是真的?给定的答案对我有用。
    • 不,实际上发生的事情是您正在返回一个已经注入的实例。看起来你选择了DomainQualifier,这个类是I18nResource注解的注解文字吗?
    • 见我的 OP:public class DomainQualifier extends AnnotationLiteral&lt;I18nResource&gt; - 所以是的。实际上,在我的真实代码中,我也将@New 用于FacesI18nService。当我在生产者方法中实例化一个新的FacesI18nService 并返回它时,成员将不会被注入。返回提供的@New FacesI18nService 时,会注入此实例中的成员。
    • 我知道这只是一篇博文——但这个人基本上在做同样的事情:byteslounge.com/tutorials/java-ee-cdi-producer-methods-tutorial(参见 6. 生产 CDI 托管 bean)
    猜你喜欢
    • 2023-03-24
    • 2021-04-01
    • 2015-11-16
    • 2020-03-21
    • 2016-01-12
    • 2020-06-19
    • 1970-01-01
    • 2012-05-29
    • 2015-02-14
    相关资源
    最近更新 更多