Kafka 模板 - 使用通配符时不适用于参数
Kafka Template - Not Applicable for the Arguments when using wildcard
我一直在构建 Kafka Producer Service。我使用 ?
通配符类型的泛型作为键值,因此它可以是 Integer
String
等
@Slf4j
public abstract class ProducerService<T> {
protected KafkaClientConfigProperties properties;
@Autowired
protected KafkaTemplate<?, T> kafkaTemplate;
public void send(T value, Iterable<Header> headers) {
ProducerRecord<?, T> record = new ProducerRecord<>(properties.getTopic(), null, null, null, value, headers);
this.kafkaTemplate.send(record);
}
然而,在使用参数 ProducerRecord
调用 send
方法时,我遇到了
的错误
The method send(ProducerRecord<capture#2-of ?,T>) in the type KafkaTemplate<capture#2-of ?,T> is not applicable for the arguments (ProducerRecord<capture#3-of ?,T>)
我也试过了
ProducerRecord<String, T> record = new ProducerRecord<>(properties.getTopic(), null, null, null, value, headers);
错误为
ProducerRecord<String, T> record = new ProducerRecord<>(properties.getTopic(), null, null, null, value, headers);
有人可以帮我理解代码有什么问题吗?谢谢
changed/fixed 这里有各种各样的东西。首先回答你问的问题。您收到相关错误的原因是,您正在创建的 ProducerRecord
接受了一个 null
键变量。
因为这个 class 是通用的,期望 K
作为键的类型和 V
作为值的类型,传入 null 意味着没有推断 K
类型的方式,这也是由于您 ?
作为键类型也是不正确的事实而增加的。
有多种方法可以缓解这种情况。
- 如果您真的有兴趣通过
headers
发送,那么您的 class 也应该接受密钥类型(而不是通配符)。考虑以下示例:
public abstract class ProducerService<K, T> {
@Autowired
protected KafkaTemplate<K, T> template;
public void send(T value, Iterable<Header> headers) {
ProducerRecord<K, T> record = new ProducerRecord<>("topic", null, null, null, value, headers);
template.send(record);
}
}
- 如果您对通过自定义 headers 发送不感兴趣,只需调用
KafkaTemplate#send
并传入要发送的 object 就足够了:
public abstract class ProducerService<T> {
@Autowired
protected KafkaTemplate<String, T> template;
public void send(T value, Iterable<Header> headers) {
template.send("topic", value);
}
}
正如您从上面的两个示例中看到的那样,键入正确的键类型而不使用通配符对您来说应该没问题。最后,还有一个建议是避免使 class 通用。
无需为特定 object 类型实现生产者服务的多个实现。您可以简单地尝试概括您的方法,以便能够处理任何类型的值。
我一直在构建 Kafka Producer Service。我使用 ?
通配符类型的泛型作为键值,因此它可以是 Integer
String
等
@Slf4j
public abstract class ProducerService<T> {
protected KafkaClientConfigProperties properties;
@Autowired
protected KafkaTemplate<?, T> kafkaTemplate;
public void send(T value, Iterable<Header> headers) {
ProducerRecord<?, T> record = new ProducerRecord<>(properties.getTopic(), null, null, null, value, headers);
this.kafkaTemplate.send(record);
}
然而,在使用参数 ProducerRecord
调用 send
方法时,我遇到了
The method send(ProducerRecord<capture#2-of ?,T>) in the type KafkaTemplate<capture#2-of ?,T> is not applicable for the arguments (ProducerRecord<capture#3-of ?,T>)
我也试过了
ProducerRecord<String, T> record = new ProducerRecord<>(properties.getTopic(), null, null, null, value, headers);
错误为
ProducerRecord<String, T> record = new ProducerRecord<>(properties.getTopic(), null, null, null, value, headers);
有人可以帮我理解代码有什么问题吗?谢谢
changed/fixed 这里有各种各样的东西。首先回答你问的问题。您收到相关错误的原因是,您正在创建的 ProducerRecord
接受了一个 null
键变量。
因为这个 class 是通用的,期望 K
作为键的类型和 V
作为值的类型,传入 null 意味着没有推断 K
类型的方式,这也是由于您 ?
作为键类型也是不正确的事实而增加的。
有多种方法可以缓解这种情况。
- 如果您真的有兴趣通过
headers
发送,那么您的 class 也应该接受密钥类型(而不是通配符)。考虑以下示例:
public abstract class ProducerService<K, T> {
@Autowired
protected KafkaTemplate<K, T> template;
public void send(T value, Iterable<Header> headers) {
ProducerRecord<K, T> record = new ProducerRecord<>("topic", null, null, null, value, headers);
template.send(record);
}
}
- 如果您对通过自定义 headers 发送不感兴趣,只需调用
KafkaTemplate#send
并传入要发送的 object 就足够了:
public abstract class ProducerService<T> {
@Autowired
protected KafkaTemplate<String, T> template;
public void send(T value, Iterable<Header> headers) {
template.send("topic", value);
}
}
正如您从上面的两个示例中看到的那样,键入正确的键类型而不使用通配符对您来说应该没问题。最后,还有一个建议是避免使 class 通用。
无需为特定 object 类型实现生产者服务的多个实现。您可以简单地尝试概括您的方法,以便能够处理任何类型的值。