实现注解式注入kafkaTemplate 生产者和消费者,简化配置文件

目录

消费者工厂
/**
* 消费者工厂
*/
@EnableKafka
@Configuration
public class KafkaConsumerFactory { @Autowired
private ApplicationContext context; /**
* 获取消费者工厂
*/
public ConsumerFactory<String, String> consumerFactory(String kafkaBroker) { // 消费者配置信息
Map<String, Object> props = new HashMap<>();
props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, kafkaBroker);
props.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, Boolean.TRUE);
props.put(ConsumerConfig.MAX_POLL_RECORDS_CONFIG, 10);
props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class); return new DefaultKafkaConsumerFactory<>(props);
} /**
* 容器配置
*
* @param groupId 组名
* @param clazz 消费者监听器
* @param topicName topicName
* @return 容器配置
*/
public ContainerProperties containerProperties(String groupId, Class clazz, String topicName) { ContainerProperties containerProperties = new ContainerProperties(topicName);
containerProperties.setAckMode(AbstractMessageListenerContainer.AckMode.RECORD);
containerProperties.setGroupId(groupId);
containerProperties.setMessageListener(context.getBean(clazz));
return containerProperties;
} /**
* 获取消费容器实例
*
* @param kafkaBroker kafka server
* @param groupId 组名
* @param clazz 消费者监听器
* @param topicName topicName
* @param threadCount 消费线程数
* @return 消息监听容器
*/
public ThreadMessageListenerContainer<String, String> kafkaListenerContainer(
String kafkaBroker, String groupId, Class clazz, String topicName, int threadCount) { ThreadMessageListenerContainer<String, String> container
= new ThreadMessageListenerContainer<>(
consumerFactory(kafkaBroker), containerProperties(groupId, clazz, topicName));
container.setConcurrency(threadCount);
container.getContainerProperties().setPollTimeout(3000);
return container;
} }

生产者工厂
/**
* 生产者工厂
*/
@EnableKafka
@Configuration
public class KafkaProducerFactory { @Autowired
private ApplicationContext context; /**
* 获取生产者工厂
*/
public ProducerFactory<String, String> producerFactory(String kafkaBroker) { Map<String, Object> props = new HashMap<>();
props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, kafkaBroker);
props.put(ProducerConfig.RETRIES_CONFIG, 1);
props.put(ProducerConfig.ACKS_CONFIG, "all");
props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class); return new DefaultKafkaProducerFactory<>(props);
} /**
* 注册生产者实例
*/
public KafkaTemplate<String, String> kafkaTemplate(String kafkaBroker, String topicName, Class clazz) { KafkaTemplate<String, String> template = new KafkaTemplate<>(producerFactory(kafkaBroker), Boolean.FALSE);
template.setDefaultTopic(topicName);
template.setProducerListener((ProducerListener<String, String>) context.getBean(clazz));
return template;
}
}

初始化监听器、实例

/**
* kafka 初始化
*/
@Component
public class KafkaInit { /**
* kafka server
*/
@Value("${kafka.servers}")
private String kafkaBroker; /**
* 组名
*/
@Value("${kafka.group}")
private String groupId; /**
* topicName
*/
@Value("${kafka.topic}")
private String topicName; /**
* 消费者工厂
*/
@Autowired
private KafkaConsumerFactory kafkaConsumerFactory; /**
* 生产者工厂
*/
@Autowired
private KafkaProducerFactory kafkaProducerFactory; /**
* 在服务器加载Servlet的时候运行,并且只会被服务器调用一次
*/
@PostConstruct
public void consumer() { kafkaConsumerFactory.kafkaListenerContainer(kafkaBroker, groupId, TestConsumerListener.class, topicName, 6)
.startContainer();
// 加载消费者listener } /**
* 获取生产者实例
*/
@Bean("testSender")
public KafkaTemplate<String, String> testSender() { return kafkaProducerFactory.kafkaTemplate(kafkaBroker, topicName, DefaultProducerListener.class);
} }

用于手动控制容器加载

/**
* 继承消息监听容器
*/
public class ThreadMessageListenerContainer<K, V> extends ConcurrentMessageListenerContainer<K, V> { public ThreadMessageListenerContainer(ConsumerFactory<K, V> consumerFactory, ContainerProperties containerProperties) {
super(consumerFactory, containerProperties);
} public void startContainer() {
super.doStart();
}
}
生产者监听器
/**
* 默认生产者监听器
*/
@Component
public class DefaultProducerListener extends ProducerListenerAdapter { /**
* 发送消息成功后调用
*/
@Override
public void onSuccess(String topic, Integer partition, Object key,
Object value, RecordMetadata recordMetadata) {
super.onSuccess(topic, partition, key, value, recordMetadata);
System.out.println("消息发送成功!");
} /**
* 发送消息错误后调用
*/
@Override
public void onError(String topic, Integer partition, Object key,
Object value, Exception exception) {
super.onError(topic, partition, key, value, exception);
System.out.println("消息发送失败!");
} /**
* 是否开启发送监听
*
* @return true开启,false关闭
*/
@Override
public boolean isInterestedInSuccess() {
return true;
} }
消费者监听器
/**
* 消费者监听器
*/
@Component
public class TestConsumerListener implements MessageListener<String, String> { /**
* 消费消息
*
* @param record 消息
*/
@Override
public void onMessage(ConsumerRecord<String, String> record) { System.out.println(record);
}
}
消息发送测试
/**
* 消息发送
*/
@Component
public class TestProducerSender { /**
* 转账队列发送
*/
@Autowired
@Qualifier("testSender")
private KafkaTemplate kafkaTemplate; /**
* 消息发送测试
*/
public void sendMessage() { kafkaTemplate.sendDefault("message test");
}
}

Spring KafkaTemplate 注解式实现 工厂模式的更多相关文章

  1. spring中注解式事务不生效的问题

    常用的解决方法可以百度,我针对我的问题描述一下 Mysql中InnoDB引擎才支持事务, MyISAM不支持事务. 当你尝试了各种方法解决spring中注解式事务不生效时, 一定要查看一下数据库中表的 ...

  2. spring(7)--注解式控制器的数据验证、类型转换及格式化

    7.1.简介 在编写可视化界面项目时,我们通常需要对数据进行类型转换.验证及格式化. 一.在Spring3之前,我们使用如下架构进行类型转换.验证及格式化: 流程: ①:类型转换:首先调用Proper ...

  3. spring(6)--注解式控制器

    6.1.注解式控制器简介 一.Spring2.5之前,我们都是通过实现Controller接口或其实现来定义我们的处理器类.已经@Deprecated.   二.Spring2.5引入注解式处理器支持 ...

  4. Spring常用注解式开发

    1.组件注册@Configuration.@Bean给容器中注册组件. 注解,@Configuration告诉Spring这是一个配置类,相当于bean.xml配置文件. 注解,@Bean给Sprin ...

  5. spring + mybatis 注解式事务不回滚的原因分析 @Transactional

    在一个项目中发现spring的事务无法回滚. DEBUG: org.mybatis.spring.SqlSessionUtils - SqlSession [org.apache.ibatis.ses ...

  6. Spring MVC 注解式

    1.注解式控制器简介 一.Spring2.5之前,我们都是通过实现Controller接口或其实现来定义我们的处理器类.已经@Deprecated.   二.Spring2.5引入注解式处理器支持,通 ...

  7. Spring 16: SM(Spring + MyBatis) 注解式事务 与 声明式事务

    Spring事务处理方式 方式1:注解式事务 使用@Transactional注解完成事务控制,此注解可添加到类上,则对类中所有方法执行事务的设定,注解添加到方法上,则对该方法执行事务处理 @Tran ...

  8. Spring MVC注解式开发

    MVC注解式开发即处理器基于注解的类开发, 对于每一个定义的处理器, 无需在xml中注册. 只需在代码中通过对类与方法的注解, 即可完成注册. 定义处理器 @Controller: 当前类为处理器 @ ...

  9. Spring中常见的设计模式——工厂模式

    一.简单工厂模式 简单工厂模式(Simple Factory Pattern)由一个工厂对象决定创建哪一种产品类的实例,简单工厂模式适用于工厂类负责创建对象较少的情况,且客户端只需要传入工厂类的参数, ...

随机推荐

  1. SQL结果统计 GROUP BY

    在结果几种,使用GROUP BY进行相同项求和的时候SELECT的字段要与GROUP BY后面的一一对应. select M.TIME,M.PRODUCTMODEL,M.PROCESS_PRODUCT ...

  2. vs中free内存失败

    关于vs中free内存失败: 主要有以下两个原因: 1. 函数参数调用写错.特别是传指针进去的时候,若形参与实参不对应,会出错. 2. 内存分配不够,这个原因主要是因为程序中访问到了内存外的地址,即使 ...

  3. sh_05_非公勿入

    sh_05_非公勿入 # 练习3: 定义一个布尔型变量 is_employee,编写代码判断是否是本公司员工 is_employee = False # 如果不是提示不允许入内 # 在开发中,通常希望 ...

  4. 运行roslaunch启动节点报错找不到节点

    报错信息: ERROR: cannot launch node of type [${package_name}/${package_name}_node]: can't locate node [$ ...

  5. phpcms v9 更改首页

    phpcms v9的默认首页是(域名/index.php?m=content&c=index&a=init)那为什么你直接敲一个域名它就自己进 去了呢,其实在caches-->c ...

  6. ACM ICPC 2011-2012 Northeastern European Regional Contest(NEERC)G GCD Guessing Game

    G: 要你去才Paul的年龄,Paul的年龄在1~n之间,你每猜一个Paul会告诉你,你猜的这个数和他年龄的gcd,问在最坏情况下最少要猜多少次. 题解: 什么是最坏情况,我们直到如果他的年龄是1的话 ...

  7. serial redirection

    int setOption(int fd,int nSpeed, int nBits, char mode,char nEvent, int nStop) { struct termios newti ...

  8. lgb参数及调参

    1 参数含义 max_depth: 设置树的最大深度,默认为-1,即不限制最大深度,它用于限制过拟合 num_leave: 单颗树的叶子数目,默认为31 eval_metric: 评价指标,可以用lg ...

  9. 中国MOOC_零基础学Java语言_第5周 数组

    第5周 数组 5.1 数组 5.2 数组计算 public class Main { public static void main(String[] args) { for (int i = 1; ...

  10. Java 项目管理工具 - Maven

    类似于 PHP 中的 Composer,NodeJS 中的 npm,Java 用 Maven 来管理依赖关系. 实际上,Maven 负责管理 Java 项目开发过程中的几乎所有的东西: 版本控制:Ma ...