HK2泛型子类与非泛型接口绑定问题求助
问题背景
我有如下2个接口及对应的实现类:
KafkaConsumerExecutor(接口)DefaultExecutor(上述接口的实现类)ConsumerRecordsProcessor(接口)LastOnlyRecordsProcessor(上述接口的实现类)
核心接口与实现类代码
public interface KafkaConsumerExecutor { void start(); void stop(); } public class DefaultExecutor<MESSAGE_TYPE> implements KafkaConsumerExecutor { private final ConsumerRecordsProcessor<MESSAGE_TYPE> consumerRecordsProcessor; @Override public void start(){} //processStuff @Override public void stop(){} //kill } public interface ConsumerRecordsProcessor<MESSAGE_TYPE> { void process(Iterable<ConsumerRecord<String, MESSAGE_TYPE>> consumerRecords); }
public class LastOnlyRecordsProcessor<MESSAGE_TYPE extends Serializable> implements ConsumerRecordsProcessor<MESSAGE_TYPE> { public void process(Iterable<ConsumerRecord<String, MESSAGE_TYPE>> consumerRecords){ // process stuff. } }
启动类代码
@Inject public KafkaListenerManagerImpl(ConsumerExecutor consumerExecutor) { this.consumerExecutor= consumerExecutor; }
问题描述
无法将泛型实现类DefaultExecutor<String>绑定到KafkaConsumerExecutor,尝试三种绑定方式均失败:
方式1
bind(new TypeLiteral<DefaultExecutor<String>>() {}).to(new TypeLiteral<ConsumerExecutor>(){}); bind(LastOnlyRecordsProcessor.class).to(new TypeLiteral<ConsumerRecordsProcessor<Request>>() {});
报错:
Caused by: java.lang.IllegalArgumentException: argument type mismatch
方式2
bind(DefaultExecutor.class).to(new TypeLiteral<ConsumerExecutor>() {}); bind(LastOnlyRecordsProcessor.class).to(new TypeLiteral<ConsumerRecordsProcessor<String>>() {});
报错:
UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=ConsumerRecordsProcessor<MESSAGE_TYPE>,parent=DefaultExecutor,qualifiers={},position=1,optional=false,self=false,unqualified=null,1237264838)
方式3
bind(DefaultExecutor.class).to(new TypeLiteral<ConsumerExecutor>() {}); bind(new TypeLiteral<LastOnlyRecordsProcessor<String>>() {}).to(new TypeLiteral<ConsumerRecordsProcessor<String>>() {});
报错:
Caused by: org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=ConsumerRecordsProcessor<MESSAGE_TYPE>,parent=DefaultExecutor,qualifiers={},position=1,optional=false,self=false,unqualified=null,202064342)
核心需求
- 将
DefaultExecutor绑定到KafkaConsumerExecutor - 将
LastOnlyRecordsProcessor绑定到ConsumerRecordsProcessor
错误分析与解决方案
错误原因
- 绑定方向颠倒:HK2的
bind().to()语法规则是bind(接口).to(实现类),你之前的写法把实现类和接口的位置搞反了,导致类型匹配失败。 - 泛型类型未精准匹配:
DefaultExecutor<String>依赖的是ConsumerRecordsProcessor<String>,但原有绑定未明确关联泛型参数,HK2无法识别匹配的依赖。 - 启动类接口名称笔误:
KafkaListenerManagerImpl注入的ConsumerExecutor应为KafkaConsumerExecutor,名称不匹配会导致注入失败。 - 缺失构造方法:
DefaultExecutor未提供注入ConsumerRecordsProcessor的构造方法,HK2无法完成依赖注入。
正确实现步骤
1. 修正DefaultExecutor的构造方法
添加带@Inject注解的构造方法,让HK2可以注入依赖:
public class DefaultExecutor<MESSAGE_TYPE> implements KafkaConsumerExecutor { private final ConsumerRecordsProcessor<MESSAGE_TYPE> consumerRecordsProcessor; @Inject public DefaultExecutor(ConsumerRecordsProcessor<MESSAGE_TYPE> consumerRecordsProcessor) { this.consumerRecordsProcessor = consumerRecordsProcessor; } @Override public void start() { // processStuff } @Override public void stop() { // kill } }
2. 修正启动类的注入类型
@Inject public KafkaListenerManagerImpl(KafkaConsumerExecutor consumerExecutor) { this.consumerExecutor = consumerExecutor; }
3. 正确的HK2绑定配置
明确绑定泛型版本的实现类到对应接口,确保泛型参数匹配:
// 绑定DefaultExecutor<String>到KafkaConsumerExecutor bind(new TypeLiteral<KafkaConsumerExecutor>() {}) .to(new TypeLiteral<DefaultExecutor<String>>() {}); // 绑定LastOnlyRecordsProcessor<String>到ConsumerRecordsProcessor<String> bind(new TypeLiteral<ConsumerRecordsProcessor<String>>() {}) .to(new TypeLiteral<LastOnlyRecordsProcessor<String>>() {});
这样就能解决类型不匹配和依赖未满足的问题。
内容的提问来源于stack exchange,提问作者Bleach

