原理:Spring与redis整合后,配置的监听器会对项目进行监听,每当调用RedisTemplate这个类的convertAndSend(java.lang.String channel, java.lang.Object message)方法,像指定的频道(在配置文件之中)发送一条消息,该消息就会被监听器监听到,进而实现发布订阅功能。
一、导入maven依赖
spring集成redis需要导入的maven依赖有两个,如下:
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.6.2.RELEASE</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.8.2</version>
</dependency>
二、新建redis配置文件,配置redis服务器相关信息
文件名为:redis.properties
redis.host=localhost
redis.port=6379
redis.password=
redis.database=0
redis.timeout=1000
#session valid time
redis.maxInactiveIntervalInSeconds=1800
#redis pool config
redis.pool.maxTotal=300
redis.pool.maxIdle=5
redis.pool.minIdle=1
redis.pool.maxWaitMillis=6000
redis.pool.testWhileIdle=true
redis.testOnBorrow=true
三、新建redis配置文件redis-context.xml文件,注册redis相关配置信息
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p" xmlns:redis="http://www.springframework.org/schema/redis"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/redis http://www.springframework.org/schema/redis/spring-redis.xsd">
<!-- TODO 定义 spring-redis 集成配置,包括常用操作和集成redis发布/订阅功能 -->
<!-- TODO 通过在 spring-mvc.xml 中使用 import 标签导入此配置文件 -->
<context:component-scan base-package="xin.shenwan.redis"/>
<!-- 引入redis服务器配置 -->
<context:property-placeholder location="classpath:/redis.properties" file-encoding="utf-8"
ignore-unresolvable="true"/>
<!-- 定义Spring RedisTemplate -->
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"
p:connectionFactory-ref="redisConnectionFactory"/>
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxIdle" value="${redis.pool.maxIdle}"/>
<property name="maxTotal" value="${redis.pool.maxTotal}"/>
<property name="testOnBorrow" value="${redis.pool.testWhileIdle}"/>
</bean>
<!-- 定义spring-redis连接工厂 -->
<bean id="redisConnectionFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="usePool" value="true"/>
<property name="hostName" value="${redis.host}"/>
<property name="port" value="${redis.port}"/>
<property name="password" value="${redis.password}"/>
<property name="timeout" value="${redis.timeout}"/>
<property name="database" value="${redis.database}"/>
<constructor-arg index="0" ref="jedisPoolConfig"/>
</bean>
<!-- 定义Spring RedisTemplate -->
<bean id="stringRedisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">
<property name="connectionFactory" ref="redisConnectionFactory"/>
<property name="keySerializer" ref="stringRedisSerializer"/>
<property name="valueSerializer" ref="stringRedisSerializer"/>
<property name="hashKeySerializer" ref="stringRedisSerializer"/>
<property name="hashValueSerializer" ref="stringRedisSerializer"/>
</bean>
<!-- 定义Spring Redis的序列化器 -->
<!-- String序列化 -->
<bean id="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
<!-- jdk序列化-->
<bean id="jdkSerializer" class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>
<!-- 将监听实现类注册到spring容器中 -->
<bean id="dataSyncEventListener" class="xin.shenwan.redis.DataSyncEventListener"/>
<!-- 注册监听器并引入监听实现类 -->
<bean id="messageListener" class="org.springframework.data.redis.listener.adapter.MessageListenerAdapter">
<property name="delegate" ref="dataSyncEventListener"/>
<property name="serializer" ref="stringRedisSerializer"/>
<!--<property name="serializer" ref="jdkSerializer" />-->
</bean>
<!-- 消息监听:其中可以通过method方法自定义—监听实现类中用来处理消息的方法 -->
<redis:listener-container>
<!--指定消息处理方法,序列化方式及主题名称-->
<redis:listener ref="messageListener" method="onMessage" serializer="stringRedisSerializer" topic="channel1.0"/>
<!--<redis:listener ref="messageListener" method="onMessage" serializer="jdkSerializer" topic="java"/>-->
</redis:listener-container>
</beans>
四、spring-mvc.xml配置如下
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd">
<import resource="classpath:/redis-context.xml"/>
<!--spring包扫描-->
<context:component-scan base-package="xin.shenwan.*"/>
<!--redis配置文件-->
<context:property-placeholder location="classpath:/redis.properties" file-encoding="utf-8"
ignore-unresolvable="true"/>
<!--开启springmvc注解支持-->
<mvc:annotation-driven/>
<!-- 定义跳转的文件的前后缀 ,视图模式配置-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 自动给后面action的方法return的字符串加上前缀和后缀,变成一个 可用的url地址 -->
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!--对静态资源不做拦截,交给web容器-->
<mvc:default-servlet-handler/>
</beans>
五、web.xml配置如下(仅供参考,看实际情况配置)
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
<!-- Spring和mybatis的配置文件 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mybatis.xml</param-value>
</context-param>
<!-- 编码过滤器 -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<async-supported>true</async-supported>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Spring监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 防止Spring内存溢出监听器 -->
<listener>
<listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
</listener>
<!--Spring MVC servlet-->
<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<!-- 此处可以可以配置成*.do,对应struts的后缀习惯 -->
<url-pattern>/</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>/index.jsp</welcome-file>
</welcome-file-list>
</web-app>
六、新建一个发布信息的类:发布的消息不可以为null,否则redis在set消息时会报NullPointerException
package xin.shenwan.redis;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
/**
* @author 12450
*/
@Component
public class SendMessage {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
/**
* 该方法调用redisTemplate发布信息,
* @param channel 发布信息的频道名称
* @param message 要发布的信息
*/
public synchronized void sendMessage(String channel, String message) {
redisTemplate.convertAndSend(channel, message);
}
}
七、新建用于监听redis发布并获取到发布信息的监听类(该类实现了redis监听接口)
这里需要注意:实际情况中采用哪一种序列化方式合适就选择哪一种,选择时配置文件中的相关配置也需要进行更改
package xin.shenwan.redis;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import xin.shenwan.socket.RsSocket;
/**
* @author 12450
*/
public class DataSyncEventListener implements MessageListener {
@Autowired
private RedisSerializer<String> stringRedisSerializer;
@Autowired
private JdkSerializationRedisSerializer jdkSerializationRedisSerializer;
/**
* 需要重写MessageListener的方法
*
* @param message
* @param bytes
*/
@Override
public void onMessage(Message message, byte[] bytes) {
String channel = stringRedisSerializer.deserialize(message.getChannel());
Object object = stringRedisSerializer.deserialize(message.getBody());
//采用jdk方式进行序列化
/*Object channel = jdkSerializationRedisSerializer.deserialize(message.getChannel());
Object object = jdkSerializationRedisSerializer.deserialize(message.getBody());*/
System.out.println("channel is :" + channel);
//向客户端发送的信息
String messageToUser = object.toString();
System.out.println("message is :" + messageToUser);
}
}
八、测试类
package xin.shenwan.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import xin.shenwan.redis.SendMessage;
@Controller
@RequestMapping(value = "/test")
public class RedisTest {
@Autowired
SendMessage sendMessage;
@RequestMapping(value = "/sendMsg")
public void redis() {
for (int i = 0; i < 10; i++) {
sendMessage.sendMessage("channel1.0", "第" + i + "次发送信息");
}
}
}
启动项目访问链接,注意看控制台输出:
只是很基础的入门总结,欢迎各位大神提出改进意见。