0

嗨,我定义了以下限定符类型..

@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.FIELD })
public @interface SortAndFilterType {

/**
 * The value for the sort and filter.
 *
 * @return the sort and filter type value.
 */
String value();
}

以及其中的两个实现。

@SortAndFilterType("Users")
public class UserSortAndFilterProviderImpl implements SortAndFilterProvider<Field, User>       {}

@SortAndFilterType("ReportsList")
public class ReportListSortAndFilterProviderImpl implements SortAndFilterProvider<Field, ReportList> {}

我从客户端注入..

@Inject
@SortAndFilterType("Users")
private SortAndFilterProvider mSortAndFilterProvider;

每件事在运行时都可以正常工作..

但是当我运行单元测试时问题就来了..

我收到以下异常..

org.jboss.weld.exceptions.DeploymentException: WELD-001408: 在注入点 [BackedAnnotatedField] @Inject @SortAndFilterType private com.collabnet.ctf.saturn.client.apps.users.ChangeUsersStatus 带有限定符的 SortAndFilterProvider 类型的依赖关系不满足。 mSortAndFilterProvider

我从这样的单元测试中调用它..它使用@RunWith(CdiRunner.class) 运行

@Produces
@SortAndFilterType("Users")
@Mock
private SortAndFilterProvider mSortAndFilterProvider;

这里出了什么问题?

4

2 回答 2

1

CDI 的一个好处(这对您来说是个问题)是它的类型安全解析将参数化类型中的参数考虑在内。换句话说:“CDI 中没有类型擦除”该规范对参数化类型解析非常详细:

如果参数化 bean 类型具有相同的原始类型并且对于每个参数,则认为参数化 bean 类型可分配给参数化必需类型:

  • 所需类型参数和bean类型参数是具有相同原始类型的实际类型,并且,如果类型被参数化,则bean类型参数可根据这些规则分配给所需类型参数,或

  • 必需的类型参数是通配符,bean 类型参数是实际类型,并且实际类型可分配给通配符的上限(如果有),并且可以从通配符的下限(如果有)分配,或

  • 所需的类型参数是通配符,bean 类型参数是类型变量,类型变量的上限可分配给通配符的上限(如果有)或从通配符的上限(如果有)分配,并且可以从下限(如果有)分配,通配符,或

  • 所需的类型参数是实际类型,bean 类型参数是类型变量,并且实际类型可分配给类型变量的上限(如果有),或

  • 所需类型参数和 bean 类型参数都是类型变量,并且所需类型参数的上限可分配给 bean 类型参数的上限(如果有)。

您可以在此处阅读原文:http: //docs.jboss.org/cdi/spec/1.2/cdi-spec.html#assignable_parameters

现在 Weld 1.x 对这一点不够严格,并接受将参数化类型分配给其原始类型。这可能就是为什么您在运行时没有问题(例如使用 JBoss AS 7.x 运行)并且在您的测试中遇到这个问题(cdi-runner 可能使用 Weld 2.x)。是的,我在这里猜测,我可能是错的,这就是为什么提供您在问题中使用的框架版本总是一件好事。

无论如何,您应该通过将注入点更改为来解决您的问题

@Inject
@SortAndFilterType("Users")
private SortAndFilterProvider<Field,?> mSortAndFilterProvider; 

它遵守规范,可在 Weld 1.x 和 2.x 下工作。

顺便说一句,您可能不需要您的限定词,因为之间不会有任何歧义:

@Inject
private SortAndFilterProvider<Field,User> mSortAndFilterProvider1;

@Inject
private SortAndFilterProvider<Field,ReportList> mSortAndFilterProvider2;
于 2014-09-17T09:49:14.393 回答
0

Hi that's Exactly the Problem. and my Runtime uses Jboss 7 and the Test Environment uses CDI 2.x.

After adding the type parameters to the Injection point it works perfectly fine.

Thanks a lot.

于 2014-09-17T15:04:46.913 回答