Java CDI泛型类型实例注入问题:GenericValidator集合为空
解决CDI泛型Bean注入为空的问题
我来帮你排查这个问题——你的Instance<GenericValidator<T>> delegators是空集合,大概率是CDI没办法正确识别到你的泛型实现类,或者你的类缺少必要的CDI注解。咱们一步步来理清楚:
1. 给具体Validator类添加CDI Bean注解
你给出的String类型Validator实现代码里,只写了@Override的方法,但这个类本身没有任何CDI相关的注解。CDI容器只会管理那些被标记为Bean的类,哪怕是默认的@Dependent作用域,你也需要显式标注(部分容器支持无注解,但为了兼容性最好加上)。
修改你的实现类:
@Dependent // 或者根据需求用@ApplicationScoped、@RequestScoped等 public class StringPasswordValidator implements GenericValidator<String> { @Override public String getConfigurationCode() { return "GENERIC_PASSWORD"; } @Override public ErrorMessages validate(String toValidate) { // 这里实现你的验证逻辑 return null; } }
2. 解决泛型类型捕获的问题
CDI在处理泛型类型时,有时候无法自动推断T的具体类型,导致找不到匹配的Bean。这时候可以用TypeLiteral来明确指定泛型类型,帮CDI定位到正确的实现类。
修改GenericValidatorConstructor的getValidatorsByConfig方法:
import javax.enterprise.inject.Instance; import javax.enterprise.util.TypeLiteral; import java.util.ArrayList; import java.util.List; public class GenericValidatorConstructor<T> { @Inject private Instance<GenericValidator<T>> delegators; public List<GenericValidator<T>> getValidatorsByConfig(String configCode) { List<GenericValidator<T>> result = new ArrayList<>(); // 通过TypeLiteral明确泛型的具体类型 Instance<GenericValidator<T>> typedDelegators = delegators.select(new TypeLiteral<GenericValidator<T>>() {}); for (GenericValidator<T> validator : typedDelegators) { if (configCode != null && configCode.equals(validator.getConfigurationCode())) { result.add(validator); } } return result; } }
3. 检查CDI容器的扫描范围
确保你的Validator实现类在CDI容器的扫描范围内:
- 如果是Java EE项目,确认
beans.xml存在(CDI 1.1+默认会扫描所有类,但有些老环境可能需要显式配置扫描包); - 确保你的实现类所在的包被容器扫描到,没有被排除在扫描范围外。
4. 排查限定符冲突(如果有)
如果你给Validator类添加了自定义的限定符注解,那你的Instance<GenericValidator<T>>也需要匹配对应的限定符才能注入成功。不过从你的代码来看,应该没有这个问题,但可以确认一下。
先从第一步和第二步开始调整,这两个是最可能导致delegators为空的原因。调整后再测试调用,应该就能正常获取到你的String类型Validator了。
内容的提问来源于stack exchange,提问作者tassadar
相关产品推荐
相关产品推荐

