不能对包含泛型的接口使用限定符
Can't use qualifiers with interface that consist generics
遇到带有限定符和泛型的 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;
得到相同的结果。
知道如何将注入与限定符和泛型一起使用吗?
我已经重新创建了样本,它应该可以正常工作。
预选赛:
@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);
}
}
还有一个测试class:
@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));
}
}
您可以将此 class 和 运行 复制为:
java org.jboss.weld.environment.se.StartMain
在解析过程中,将考虑通用参数和限定符注释。
您的第一种方法不起作用的原因是因为您违反了 CDI spec assignability rules(第一行)。简而言之 - 注入原始类型仅适用于未绑定/Object
类型。
但是,第二种方法确实有效——我刚刚使用 Weld SE 进行了验证。例如:
@Inject
@SomeQualifier
SomeInterface<AnotherClass> instance;
我想你可能忘了重新编译你的代码什么的?仔细检查,因为我确定这有效。那,或者你的代码有其他问题。
遇到带有限定符和泛型的 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;
得到相同的结果。
知道如何将注入与限定符和泛型一起使用吗?
我已经重新创建了样本,它应该可以正常工作。
预选赛:
@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);
}
}
还有一个测试class:
@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));
}
}
您可以将此 class 和 运行 复制为:
java org.jboss.weld.environment.se.StartMain
在解析过程中,将考虑通用参数和限定符注释。
您的第一种方法不起作用的原因是因为您违反了 CDI spec assignability rules(第一行)。简而言之 - 注入原始类型仅适用于未绑定/Object
类型。
但是,第二种方法确实有效——我刚刚使用 Weld SE 进行了验证。例如:
@Inject
@SomeQualifier
SomeInterface<AnotherClass> instance;
我想你可能忘了重新编译你的代码什么的?仔细检查,因为我确定这有效。那,或者你的代码有其他问题。