You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Groovy如何处理可选参数?Kafka消费者功能扩展咨询

Kafka消费者类的可选参数优化问题

原Kafka消费者类代码

package kafka

@Grab(group='org.apache.kafka', module='kafka-clients', version='2.8.0')
@Grab(group='org.slf4j', module='slf4j-simple', version='2.0.0')

import com.dell.techops.TechopsKafkaProducer

import org.apache.kafka.clients.consumer.KafkaConsumer
import org.apache.kafka.clients.consumer.ConsumerConfig
import org.apache.kafka.common.serialization.StringDeserializer
import java.time.Duration
import groovy.util.logging.Slf4j


class KConsumer {
  def consumer

  KConsumer(String NexusServers, String topic, String groupId) {
    def props = new Properties()
    props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers)
    props.put(ConsumerConfig.GROUP_ID_CONFIG, groupId)
    props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName())
    props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName())

    consumer = new KafkaConsumer<String, String>(props)
    consumer.subscribe([topic])
  }
  
  List<String> consumeMessages() {
    def messages = []
    while (true) {
      def records = consumer.poll(100)
      if (!records.isEmpty()) {
        records.each { record ->
          messages.add(record.value())
        }
        return messages
      }
    }
  }
 void close() {
   consumer.close()
  }
}  

现有使用方式

def servers = "localhost:9092"
def topic = "my-topic"
def groupId = "my-group"

def consumer = new KConsumer(servers, topic, groupId)
messages = consumer.consumeMessages()
consumer.close()

需求说明

目前功能正常,希望添加一个可选参数key,当传入该参数时,仅返回对应key的消息,对应逻辑如下:

def messages = []
def records = consumer.poll(100)
for (ConsumerRecord<String, String> record : records) {
    if (record.key() == key) {
        messages.add(record.value())
    }
}

问题解答

1. 是否必须将类默认设置为接收4个参数?

不需要。Groovy提供了多种灵活处理可选参数的方式,完全可以在兼容原有3个参数调用方式的前提下,支持传入可选的key参数,无需强制修改构造函数的参数数量。

2. Groovy中是否有类似Python的*args的方式处理可选参数?

有,Groovy支持多种可选参数实现方式:

  • 默认参数值:给参数设置默认值(比如null),调用时可传可不传
  • 命名参数:通过Map接收可选参数,调用时用键值对传入,扩展性更强
  • 可变参数:用...定义可变参数列表,类似Python的*args,不过针对单个可选参数,默认参数或命名参数的可读性更好

3. 是否需要新增函数来实现该功能,还是可以复用现有的consumeMessages函数?

完全可以复用现有的consumeMessages函数,只需要给它添加可选参数即可,这样能保持API的简洁性,避免冗余函数。


优化后的代码示例

方式一:给consumeMessages添加默认参数

修改consumeMessages方法,添加可选的key参数并设默认值为null,在逻辑中判断是否需要过滤:

List<String> consumeMessages(String key = null) {
    def messages = []
    while (true) {
        def records = consumer.poll(100)
        if (!records.isEmpty()) {
            records.each { record ->
                // key为null时返回所有消息,否则只返回匹配key的消息
                if (key == null || record.key() == key) {
                    messages.add(record.value())
                }
            }
            return messages
        }
    }
}

调用方式:

// 原有调用方式不变,返回所有消息
messages = consumer.consumeMessages()

// 传入key参数,仅返回对应key的消息
messages = consumer.consumeMessages("target-key")

方式二:使用命名参数(适合后续扩展更多参数)

如果之后可能添加更多可选参数,用命名参数更清晰:

List<String> consumeMessages(Map opts = [:]) {
    def targetKey = opts.key
    def messages = []
    while (true) {
        def records = consumer.poll(100)
        if (!records.isEmpty()) {
            records.each { record ->
                if (targetKey == null || record.key() == targetKey) {
                    messages.add(record.value())
                }
            }
            return messages
        }
    }
}

调用方式:

// 原有调用方式不变
messages = consumer.consumeMessages()

// 传入命名参数
messages = consumer.consumeMessages(key: "target-key")

另外注意:原构造函数中参数名NexusServers和实际使用的bootstrapServers不匹配,建议修正为一致,避免运行时错误:

KConsumer(String bootstrapServers, String topic, String groupId) {
    def props = new Properties()
    props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers)
    // 其他代码不变
}

内容的提问来源于stack exchange,提问作者Rafa S

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 23:44:55