当使用限定符和泛型的cdi不起作用时遇到的情况。
例如,我有这样的界面:
public interface SomeInterface<T> {
T someMethod(Set<T> set);
}
它的实现(以及其他几个限定符的实现):
@SomeQualifier
public class SomeClass implements SomeInterface<AnotherClass> {
AnotherClass someMethod(Set<AnotherClass> set) {...some logic...}
}
还有一些像这样的限定词:
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD,ElementType.FIELD})
public @interface SomeQualifier {}
所以,当我把它注入一些bean(我的项目中的单例)时:
@Singleton
@Startup
public class SomeSingleton {
@Inject
@SomeQualifier
SomeInterface instance;
..usage...
}
我在部署过程中遇到异常,例如
Unsatisfied dependencies for type SomeInterface with qualifiers @SomeQualifier
但是当我在不使用泛型的情况下使用所有这些时 - 一切正常!
试着像这样注射:
@Inject
@SomeQualifier
SomeInterface<AnotherClass> instance;
得到了相同的结果。
任何想法我如何使用注入限定符和泛型?
答案 0 :(得分:2)
我重新创建了样本,它应该按预期工作。
限定符:
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({TYPE, FIELD, METHOD, PARAMETER})
public @interface BasicSample {
}
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({TYPE, FIELD, METHOD, PARAMETER})
public @interface IntegerSample {
}
实施:
public interface SampleGenericInterface<T> {
T process(Set<T> values);
}
两个实现:
@BasicSample
@ApplicationScoped
public class BasicSampleGenericInterface implements SampleGenericInterface<BigDecimal> {
@Override
public BigDecimal process(Set<BigDecimal> values) {
return values.stream().max(BigDecimal::compareTo).orElse(null);
}
}
@IntegerSample
@ApplicationScoped
public class IntegerSampleGenericInterface implements SampleGenericInterface<Integer> {
@Override
public Integer process(Set<Integer> values) {
return values.stream().min(Integer::compareTo).orElse(null);
}
}
还有一个测试类:
@ApplicationScoped
public class CdiTest {
private static final Logger LOG = Logger.getLogger(CdiTest.class.getName());
@Inject
@BasicSample
private SampleGenericInterface<BigDecimal> bigDecimalSampleGenericInterface;
@Inject
@IntegerSample
private SampleGenericInterface<Integer> integerSampleGenericInterface;
void start(@Observes ContainerInitialized containerInitialized) {
Set<BigDecimal> bigDecimals = new HashSet<>();
bigDecimals.add(BigDecimal.valueOf(837373));
bigDecimals.add(BigDecimal.valueOf(8299));
bigDecimals.add(BigDecimal.valueOf(4545454));
LOG.log(Level.INFO, "Big Decimal: {0}", bigDecimalSampleGenericInterface.process(bigDecimals));
Set<Integer> integers = new HashSet<>();
integers.add(72);
integers.add(3452);
integers.add(458923);
LOG.log(Level.INFO, "Integers: {0}", integerSampleGenericInterface.process(integers));
}
}
您可以复制此类并将其运行为:
java org.jboss.weld.environment.se.StartMain
在解决过程中,将考虑通用参数和限定符注释。
答案 1 :(得分:1)
您的第一种方法不起作用的原因是您违反了CDI spec assignability rules(第一行)。简而言之 - 注入原始类型仅适用于未绑定的/ Object
类型。
然而,第二种方法确实有效 - 我刚用Weld SE验证。 E.g:
@Inject
@SomeQualifier
SomeInterface<AnotherClass> instance;
我想您可能忘记重新编译代码或其他内容?仔细检查,因为我确定这是有效的。那,或者你在代码中还有其他一些问题。