CDI 与 @Produces 的模糊依赖 - 为什么? [英] CDI Ambiguous dependency with @Produces - why?

查看:16
本文介绍了CDI 与 @Produces 的模糊依赖 - 为什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用如下代码:

公共配置{private boolean isBatmanCar = someMethod(...);@Producespublic Car getCar(@New Car car) {如果(是蝙蝠侠汽车){car.setName("蝙蝠侠汽车");}还车;}}公车{私人字符串名称 = "NormalCar";公共无效集名称(字符串名称){this.name = 名称;}}公开演示{@注入汽车车;//其余代码}

当我将应用程序部署到 glassfish (Java EE 6 btw) 时,我得到

AmbiguousResolutionException: WELD-001318 无法解析 (...) Car 与限定符 [@Any @Default] (...) 生产者方法 [Car] 与限定符 [@Any @Default]

我知道当我将 @Alternative 添加到 Car 类时它会起作用,但我想知道这是否是正确的方法,为什么我必须这样做?

你能告诉我在这种情况下@Produces 的正确用法是什么吗?

我使用的是 Java EE 6、CDI 1.0、EJB 3.1、Glassfish 3.2

解决方案

错误来自于您有 2 个 Car 类型的 bean,一个是类,另一个是生产者.您有两个明显的解决方案来解决歧义:

首先,您将逻辑置于原始类中的 isBatmanCar 字段后面(例如在构造函数或 @PostConstruct 方法中)并移除您的生产者.这样就只剩下一个 Car bean.

或者如果你真的想要 2 个 bean 或者无法避免它,你应该为你生产的 bean 创建一个限定符:

 @Target({ TYPE, METHOD, PARAMETER, FIELD })@保留(运行时间)@记录@限定符公共@interface BatmanChecked {}

并在生产者身上使用它,

@Produces@BatmanCheckedpublic Car getCar(Car car) {...}

能够注入汽车的类型

@Inject汽车标准车;@注入@BatmanChecked汽车蝙蝠CheckedCar;

限定符是解决歧义注入的自然选择.使用 @Alternative 也可以,但这里与其说是一种好做法,不如说是一种技巧.

最后一句话:@New 在这里不是必需的,因为您的 Car bean 没有作用域(@Dependent 作用域也是如此).@New 仅在生产者注入范围不是 @Dependent 的 bean 时才有用.也就是说,如果您的 Car 类在 @Dependent 范围内,则此代码不是很有用.

I am using code like below:

public Configuration {

    private boolean isBatmanCar = someMethod(...);

    @Produces
    public Car getCar(@New Car car) {
        if(isBatmanCar) {
            car.setName("BatmanCar");
        }
        return car;
    }
}

public Car {
    private String name = "NormalCar";

    public void setName(String name) {
        this.name = name;
    }
}

public Demo {
    @Inject
    Car car;

    // rest of code
}

When I deploy an application to glassfish (Java EE 6 btw) I get

AmbiguousResolutionException: WELD-001318 Cannot resolve an ambiguous dependency between (...) Car with qualifiers [@Any @Default] (...) Producer Method [Car] with qualifiers [@Any @Default]

I know that when I add @Alternative to Car class it will work, but I wonder if this is the proper way to do it, and why do I have to do it?

Can you tell me what is the correct usage of @Produces in such case?

I'm using Java EE 6, CDI 1.0, EJB 3.1, Glassfish 3.2

解决方案

The error comes from the fact that you have 2 beans of type Car, one being the class, the other being the producer. You have 2 obvious solutions to resolve the ambiguity:

First, you put the logic behind isBatmanCar field in the original class (in a constructor or a @PostConstruct method for instance) and remove your producer. That would left only one Car bean.

Or if you really want to have 2 bean or can't avoid it you should create a qualifier for your produced bean:

 @Target({ TYPE, METHOD, PARAMETER, FIELD })
 @Retention(RUNTIME)
 @Documented
 @Qualifier
 public @interface BatmanChecked {
 }

and use it on producer,

@Produces
@BatmanChecked
public Car getCar(Car car) {...}

to be able to inject the type of car

@Inject
Car stdCar;

@Inject
@BatmanChecked
Car batCheckedCar;

Qualifier is the natural option to resolve ambiguous injection. Using @Alternative also works but it's more a trick here than a good practice.

Last remark: @New is not necessary here, since your Car bean has no scope (so is @Dependent scoped). @New is only useful when a producer inject a bean with a scope that is not @Dependent. That said, this code is not very useful if your Car class is in scope @Dependent.

这篇关于CDI 与 @Produces 的模糊依赖 - 为什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆