spring-redis实现消息生产者发布和消费者订阅

Redis消息队列配置与应用
本文介绍了一种使用Redis作为消息队列的配置方法,包括连接池、哨兵配置及消息生产和消费的具体实现。

前提是你已经有一个可运行的redis的demo,直接上核心redis配置文件:

<!-- redis服务配置 开始-->
<bean class="redis.clients.jedis.JedisPoolConfig" id="poolConfig">
    <property name="maxTotal" value="${redis.maxTotal}">
    <property name="minIdle" value="${redis.minIdle}">
    <property name="maxWaitMillis" value="${redis.maxWaitTime}">
    <property name="maxIdle" value="${redis.maxIdle}">
    <property name="testOnBorrow" value="${redis.testOnBorrow}">
    <property name="testOnReturn" value="true">
    <property name="testWhileIdle" value="true">
</bean>
 
<bean class="org.springframework.data.redis.connection.RedisSentinelConfiguration" id="sentinelConfiguration">
    <property name="master">
        <bean class="org.springframework.data.redis.connection.RedisNode">
            <property name="name" value="${redis.sentinel.masterName}"></property>
        </bean>
    </property>
    <property name="sentinels">
        <set>
            <bean class="org.springframework.data.redis.connection.RedisNode">
                <constructor-arg name="host" value="${redis.sentinel1.host}"></constructor-arg>
                <constructor-arg name="port" value="${redis.sentinel1.port}"></constructor-arg>
            </bean>
            <bean class="org.springframework.data.redis.connection.RedisNode">
                <constructor-arg name="host" value="${redis.sentinel2.host}"></constructor-arg>
                <constructor-arg name="port" value="${redis.sentinel2.port}"></constructor-arg>
            </bean>
            <bean class="org.springframework.data.redis.connection.RedisNode">
                <constructor-arg name="host" value="${redis.sentinel3.host}"></constructor-arg>
                <constructor-arg name="port" value="${redis.sentinel3.port}"></constructor-arg>
            </bean>
        </set>
    </property>
</bean>
 
<bean class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" id="connectionFactory" p:password="${redis.sentinel.password}">
    <constructor-arg name="sentinelConfig" ref="sentinelConfiguration"></constructor-arg>
    <constructor-arg name="poolConfig" ref="poolConfig"></constructor-arg>
    <property name="database" value="${redis.database}">
</property></bean>
 
<bean class="org.springframework.data.redis.core.RedisTemplate" id="redisTemplate">
    <property name="connectionFactory" ref="connectionFactory">
</property></bean>
 
<bean class="com.hthl.xxtd.service.redis.RedisService" id="redisService">
    <property name="redisTemplate" ref="redisTemplate"></property>
</bean>
 
<!-- 对象序列化方式 -->    
<bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" id="jdkSerializer">    
 
<!-- 配置监听器,redis在订阅消息时,会根据 redis:listener标签指定的方法名和通道(topic)调用不同的方法-->  
<bean class="com.hthl.xxtd.web.listen.RedisMessageListenerContainer" id="redisMsgListener">  
 
<redis:listener-container connection-factory="connectionFactory">  
    <!--  topic代表监听的通道,是一个正则匹配 -->  
    <redis:listener method="sendEmail" ref="redisMsgListener" serializer="jdkSerializer" topic="hthl_email">
</redis:listener></redis:listener-container> 
<!-- redis服务配置 结束 -->
</bean>
</bean>
消息生产者:

import java.io.Serializable;
 
import org.springframework.data.redis.core.RedisTemplate;
 
import com.hthl.xxtd.model.email.EmailRecord;
 
/**
 *
 * @see    
 * @date
 * @version  
 * @desc    消息发布者
 */
public class RedisService {
     
    private RedisTemplate<serializable, serializable=""> redisTemplate;
     
    /**
     * 发布者:发送邮件
     * */
    public void sendEmail(EmailRecord emailRecord){
        redisTemplate.convertAndSend("hthl_email",emailRecord);
    }
}
消费者:

import javax.annotation.Resource;
 
import org.apache.log4j.Logger;
 
import com.hthl.xxtd.model.email.EmailRecord;
import com.hthl.xxtd.service.email.EmailChannelService;
 
import net.sf.json.JSONObject;
/**
 * 订阅者
 * */
public class RedisMessageListenerContainer{
    private static final Logger logger = Logger.getLogger(RedisMessageListenerContainer.class);
    @Resource
    private EmailChannelService emailChannelService;
 
    //发送邮件
    public void sendEmail(EmailRecord  emailRecord, String channel) {
	//do something
        logger.info("订阅者"+channel+"收到邮件:"+ JSONObject.fromObject(emailRecord).toString());
    }
 
}
扩展:这里可设置多个频道,,消费者亦可根据不同channel筛选订阅



<think>嗯,用户现在想了解spring-data-redis的相关信息,包括作用使用方法。结合之前的对话历史,用户之前询问过Fastjson的用途,现在转向了Spring生态中操作Redis的工具库,说明ta可能在开发中遇到了缓存或数据存储的需求。 用户提供的5个引用内容非常有价值。引用[1][4]都强调了spring-data-redis的核心价值:用面向对象的方式操作Redis,并封装了不同客户端(Jedis/Lettuce)的差异。引用[2][5]则提到关键组件RedisTemplate序列化配置,特别是引用[5]给出了具体的依赖配置示例。引用[3]补充了SpringBoot集成场景,还提到了@Cacheable注解这个重要特性。 用户可能是个Java后端开发者,当前正在搭建或优化Redis集成模块。ta的提问比较开放,可能需要从基础概念到实操的完整指引。考虑到ta之前关注过JSON序列化(Fastjson),这次要特别注意强调spring-data-redis的序列化配置——这正是容易踩坑的地方。 需要重点覆盖四个维度:1) 库的定位(为什么不用原生客户端)2) 核心功能(Template/Repositories/Cache抽象)3) 序列化机制(对比Jackson/Fastjson的选择)4) SpringBoot集成范例。其中序列化部分要展开说明默认JDK序列化的缺陷,以及如何切换为JSON方案——这正好用户之前问的Fastjson知识关联起来。 在给出代码示例时,要区分传统Spring配置SpringBoot自动配置两种方式。对于注解驱动缓存这块,虽然引用[3]提到但未展开,可以补充@Cacheable的典型用法,毕竟这是实际开发的高频特性。 最后生成的"相关问题"要有递进性:从基础(配置调优)到进阶(事务/集群),再到生态整合(Spring Cache)。这样无论用户是初学者还是需要深度优化,都能找到延伸方向。 </think>Spring Data RedisSpring 框架中用于简化 Redis 操作的**核心模块**,它通过高度封装底层客户端(如 Jedis、Lettuce),提供统一的、面向对象的 API 来访问 Redis 数据库。以下是其核心作用与使用方法的系统说明: --- ### **一、核心作用** 1. **统一客户端抽象** 屏蔽不同 Redis 客户端(Jedis、Lettuce、JRedis)的差异[^4],开发者无需关心底层实现切换,代码兼容性强。 2. **简化操作接口** 提供 `RedisTemplate` `StringRedisTemplate` 等模板类,封装了键值操作、事务、管道、发布订阅Redis 功能[^2][^5]。 3. **无缝集成 Spring 生态** - 支持 Spring 声明式缓存注解(如 `@Cacheable`),实现方法级缓存[^3]。 -Spring Boot 深度整合,通过 `spring-boot-starter-data-redis` 实现自动配置[^3][^5]。 4. **灵活的序列化机制** 提供多种序列化策略(JDK、JSON、String 等),并支持自定义序列化器[^3][^5]。 --- ### **二、使用方法详解** #### **步骤 1:添加依赖(Spring Boot)** ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> ``` > 默认使用 Lettuce 客户端(基于 Netty,线程安全)[^5]。 #### **步骤 2:配置连接参数** ```properties # application.properties spring.redis.host=192.168.0.24 spring.redis.port=6379 spring.redis.password=yourpassword spring.redis.database=0 spring.redis.timeout=1000 # 连接超时(ms) spring.redis.lettuce.pool.max-active=200 # 连接池最大连接数 ``` > Lettuce 支持连接池共享,减少资源消耗[^5]。 #### **步骤 3:使用 RedisTemplate 操作数据** ```java @Autowired private RedisTemplate<String, Object> redisTemplate; // 写入字符串 redisTemplate.opsForValue().set("key", "value"); // 写入对象(需配置序列化) User user = new User("Alice", 25); redisTemplate.opsForValue().set("user:1", user); // 读取数据 String value = (String) redisTemplate.opsForValue().get("key"); User cachedUser = (User) redisTemplate.opsForValue().get("user:1"); ``` #### **步骤 4:自定义序列化(以 JSON 为例)** ```java @Configuration public class RedisConfig { @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(factory); // 使用 Fastjson 序列化值 GenericFastJsonRedisSerializer serializer = new GenericFastJsonRedisSerializer(); template.setValueSerializer(serializer); template.setKeySerializer(new StringRedisSerializer()); return template; } } ``` > 替换默认 JDK 序列化,避免可读性差兼容性问题[^3]。 #### **步骤 5:声明式缓存(通过注解)** ```java @Service public class UserService { @Cacheable(value = "users", key = "#id") public User getUserById(String id) { // 模拟数据库查询 return new User(id, "User" + id); } } ``` > 需在启动类添加 `@EnableCaching` 注解[^3]。 --- ### **三、关键优势** | 特性 | 说明 | |---------------------|----------------------------------------------------------------------| | **生产级可靠性** | 内置连接池管理、异常转换机制,避免资源泄漏[^2] | | **高性能** | Lettuce 基于 Netty 实现异步 I/O,支持响应式编程[^5] | | **扩展性强** | 支持 Redis 集群、哨兵模式、事务、Lua 脚本等高级特性[^4] | | **开发效率高** | 减少样板代码,通过注解快速实现缓存逻辑[^3] | --- ### **典型应用场景** 1. **分布式缓存**:加速数据库查询结果缓存(如 `@Cacheable`) 2. **会话存储**:替代 Tomcat Session 实现分布式会话 3. **消息队列**:通过 `ListOperations` 实现轻量级队列 4. **实时计数**:利用 `incr` 命令实现点赞/访问量统计 ---
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值