Java Spring mvc 操作 Redis 及 Redis 集群

来源:互联网 发布:VB6.0和MySql通讯录 编辑:程序博客网 时间:2024/05/04 09:13

关于 Redis 集群搭建可以参考我的另一篇文章 Redis集群搭建与简单使用

Redis 是什么,能做什么

Redis 是一个开源(BSD许可),内存存储的数据结构服务器,可用作数据库,高速缓存和消息队列代理。它支持字符串、哈希表、列表、集合、有序集合,位图,hyperloglogs等数据类型。内置复制、Lua脚本、LRU收回、事务以及不同级别磁盘持久化功能,同时通过Redis Sentinel 提供高可用,通过 Redis Cluster 提供自动分区。(摘自Redis 官网)

作为内存数据库,在现代互联网 web 系统中,还是主要将 Redis 作为缓存使用。大型互联网 Web 系统对性能要求很高,而在前端和数据层之间增加数据缓存已成为必不可少的手段之一,当前比较流行的两个技术就是 Redis 和 Memcached,至于两者有什么区别,不是本文要说的内容。本文主要讲 Java web 如何操作 Redis 及 Redis 集群。

一般 Java 程序操作Redis

Redis 提供了多种语言的客户端,在 Java 中最流行的是 Jedis 。访问可查看源码及使用方式。目前 Jedis 最新版本是2.9.0。无论是单机还是集群,Jedis 都有很详细的说明和实例代码,这里只做简单说明。如果用 Maven 做包管理,需要引用  jedis 包,本例使用最新的2.9.0版本,如下:

1
2
3
4
5
<dependency>
      <groupId>redis.clients</groupId>
      <artifactId>jedis</artifactId>
      <version>2.9.0</version>
</dependency>  

操作 Redis 单机

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
 
/**
 * Created by fengdezitai on 2016/10/9.
 */
public class JedisClient {
 
    privatestatic final String host= "192.168.31.121";
 
    privatestatic final JedisClient jedisClient = new JedisClient();
 
    privateJedis jedis = null;
    /**
     * 私有构造函数
     */
    privateJedisClient(){}
 
    publicstatic JedisClient getInstance(){
        returnjedisClient;
    }
 
    privateJedisPoolConfig getPoolConfig(){
        JedisPoolConfig jedisPoolConfig =new JedisPoolConfig();
        jedisPoolConfig.setMaxIdle(10);
        jedisPoolConfig.setMaxTotal(100);
        jedisPoolConfig.setMaxWaitMillis(3000);
        returnjedisPoolConfig;
    }
 
    /**
     * 添加
     * @param key
     * @param value
     * @return
     * @throws Exception
     */
    publicBoolean add(String key,String value) throwsException{
        JedisPool pool =new JedisPool(getPoolConfig(),host);
        Jedis jedis =null;
        try{
            jedis = pool.getResource();
            if(jedis.exists(key)){
                thrownew Exception(String.format("key (%s) 已存在 ",key));
            }
            jedis.set(key,value);
 
        }catch(Exception e){
            throwe;
        }
        finally{
            if(jedis!=null){
                jedis.close();
            }
        }
        pool.destroy();
        returntrue;
    }
 
    /**
     * 获取值
     * @param key
     * @return
     * @throws Exception
     */
    publicString get(String key) throwsException{
        JedisPool pool =new JedisPool(getPoolConfig(),host);
        Jedis jedis =null;
        String result ="";
        try{
            jedis = pool.getResource();
            result = jedis.get(key);
        }catch(Exception e){
            throwe;
        }
        finally{
            if(jedis!=null){
                jedis.close();
            }
        }
        pool.destroy();
        returnresult;
    }
 
    publicstatic void main(String[] args) {
        JedisClient jedisClient = JedisClient.getInstance();
        try{
            /*Boolean result = jedisClient.add("hello", "redis1");
            if(result){
                System.out.println("success");
            }*/
 
            System.out.println(jedisClient.get("hello"));
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}

操作 redis 集群

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import redis.clients.jedis.*;
import java.util.HashSet;
import java.util.Set;
 
/**
 * Created by fengdezitai on 2016/10/13.
 */
public class JedisClusterClient {
 
    privatestatic int count = 0;
 
    privatestatic final JedisClusterClient redisClusterClient = newJedisClusterClient();
 
    /**
     * 私有构造函数
     */
    privateJedisClusterClient() {}
 
    publicstatic JedisClusterClient getInstance() {
        returnredisClusterClient;
    }
 
    privateJedisPoolConfig getPoolConfig(){
        JedisPoolConfig config =new JedisPoolConfig();
        config.setMaxTotal(1000);
        config.setMaxIdle(100);
        config.setTestOnBorrow(true);
        returnconfig;
    }
 
    publicvoid SaveRedisCluster() {
        Set<HostAndPort> jedisClusterNodes =new HashSet<HostAndPort>();
        jedisClusterNodes.add(newHostAndPort("192.168.31.245",7000));
        jedisClusterNodes.add(newHostAndPort("192.168.31.245",7001));
        jedisClusterNodes.add(newHostAndPort("192.168.31.245",7002));
        jedisClusterNodes.add(newHostAndPort("192.168.31.210",7003));
        jedisClusterNodes.add(newHostAndPort("192.168.31.210",7004));
        jedisClusterNodes.add(newHostAndPort("192.168.31.210",7005));
 
        JedisCluster jc =new JedisCluster(jedisClusterNodes,getPoolConfig());
        jc.set("cluster","this is a redis cluster");
        String result = jc.get("cluster");
        System.out.println(result);
    }
 
    publicstatic void main(String[] args) {
        JedisClusterClient jedisClusterClient = JedisClusterClient.getInstance();
        jedisClusterClient.SaveRedisCluster();
    }
}  

Spring mvc 操作 Redis

在 Spring mvc 中操作 Redis ,首先当然要搭好 Spring mvc 框架了。以下是在假设 Spring mvc 环境已经架好的情况下。本例中 Spring 版本为 4.3.2 RELEASE。关于 Spring 的 maven 引用如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
<!-- spring版本号 -->
<spring.version>4.3.2.RELEASE</spring.version>
 
<!-- spring核心包 -->
    <!-- springframe start -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>${spring.version}</version>
      <exclusions>
        <exclusion>
          <groupId>commons-logging</groupId>
          <artifactId>commons-logging</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
 
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>${spring.version}</version>
    </dependency>
 
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-oxm</artifactId>
      <version>${spring.version}</version>
    </dependency>
 
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>${spring.version}</version>
    </dependency>
 
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>${spring.version}</version>
    </dependency>
 
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>${spring.version}</version>
      <exclusions>
        <exclusion>
          <groupId>commons-logging</groupId>
          <artifactId>commons-logging</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
 
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>${spring.version}</version>
    </dependency>
 
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context-support</artifactId>
      <version>${spring.version}</version>
    </dependency>
 
 
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <!-- springframe end -->

操作 Redis 单机

只用 Jedis 自己实现注入(区别于下面的引用spring-data-redis) 

把前面的 JedisClient 代码拿过来引用即可,只需实现一个访问 Redis 的 Service ,就可以集成到 Spring mvc 。Service 代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import org.springframework.stereotype.Service;
import util.JedisClient;
 
/**
 * Created by fengdezitai on 2016/10/9.
 */
@Service
public class RedisService {
 
    publicString get(String key) throwsException{
        JedisClient jedisClient = JedisClient.getInstance();//上面实现的JedisClient
        String result ="";
        try{
            result = jedisClient.get("hello");
        }catch(Exception e){
            throwe;
        }
        returnresult;
    }
}

Controller 实现如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Controller
@RequestMapping(value ="redisAllInOne")
public class RedisAllInOneController {
 
    @Autowired
    privateRedisService redisService;
 
    @RequestMapping(value ="get",method = RequestMethod.GET)
    @ResponseBody
    publicObject getByMyService(String key){
        try{
            String result = redisService.get(key);
            returnresult;
        }catch(Exception e){
            e.printStackTrace();
        }
        returnnull;
    }
}  

用 spring-data-redis 包做集成

上面是自己实现的注入,这里用 spring-data-redis 进行集成,只需简单配置即可,需要引用 maven 包如下,版本为目前最新版 1.7.2.RELEASE:

1
2
3
4
5
<dependency>
      <groupId>org.springframework.data</groupId>
      <artifactId>spring-data-redis</artifactId>
      <version>1.7.2.RELEASE</version>
    </dependency>

使用 spring-data-redis ,即省去了自己实现注入的过程,通过它提供的一些配置,即可实现连接池配置、RedisTemplate 配置、JedisConnectionFactory 配置;通过 JedisConnectionFactory 可配置连接池参数、redis 服务器、端口、密码、超时时间、database索引等;RedisTemplate 即注入的bean ,可以使用 RedisTemplate 自动注入的实体进行 redis 的一系列操作,具体看配置;

redis 服务属性配置文件:

1
2
3
4
5
6
7
redis.maxIdle=300
redis.maxWait=3000
redis.testOnBorrow=true
redis.host=192.168.31.121
redis.port=6379
redis.password=password
redis.timeout=3000

spring-data-redis xml 配置文件 redis-context.xml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<!-- jedis 连接池 配置 -->
    <beanid="poolConfig"class="redis.clients.jedis.JedisPoolConfig">
        <property name="maxIdle"value="${redis.maxIdle}"/>
        <property name="maxWaitMillis"value="${redis.maxWait}"/>
        <property name="testOnBorrow"value="${redis.testOnBorrow}"/>
    </bean>
    <!-- redis服务器中心 -->
    <beanid="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
        <property name="poolConfig"ref="poolConfig"/>
        <property name="port"value="${redis.port}"/>
        <property name="hostName"value="${redis.host}"/>
        <!--<property name="password"value="${redis.password}"/>-->
        <property name="timeout"value="${redis.timeout}"></property>
        <property name="database"value="1"></property>
    </bean>
 
    <beanid="commonRedisTemplate"class="org.springframework.data.redis.core.RedisTemplate">
        <property name="connectionFactory"ref="connectionFactory"/>
        <property name="keySerializer"ref="stringRedisSerializer"/>
        <property name="hashKeySerializer"ref="stringRedisSerializer"/>
        <property name="valueSerializer"ref="stringRedisSerializer"/>
        <property name="hashValueSerializer"ref="stringRedisSerializer"/>
    </bean>
 
    <beanid="connectionFactory1" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
        <property name="poolConfig"ref="poolConfig"/>
        <property name="port"value="${redis.port}"/>
        <property name="hostName"value="${redis.host}"/>
        <!--<property name="password"value="${redis.password}"/>-->
        <property name="timeout"value="${redis.timeout}"></property>
        <property name="database"value="2"></property>
    </bean>
 
    <beanid="stringRedisSerializer"class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
    <beanid="cacheRedisTemplate"class="org.springframework.data.redis.core.RedisTemplate">
        <property name="connectionFactory"ref="connectionFactory1"/>
        <property name="keySerializer"ref="stringRedisSerializer"/>
        <property name="hashKeySerializer"ref="stringRedisSerializer"/>
        <property name="valueSerializer"ref="stringRedisSerializer"/>
        <property name="hashValueSerializer"ref="stringRedisSerializer"/>
    </bean>

之后在 spring 配置文件中引用以上文件:

1
<importresource="redis-context.xml"/>  

解释一下上面的配置:

poolConfig 即配置 redis 连接池,之后配置了两个 JedisConnectionFactory 和 RedisTemplate ,一个 RedisTemplate 对应一个 JedisConnectionFactory ,这样可以配置根据场景配置不同的 Redis 连接,比如超时时间要求不一致、database 0-15 可以存储不同的数据等。这里就配置了database 1 和 2 ,调用 commonRedisTemplate 会存到 database1 ,调用 cacheRedisTemplate 会存到 database2。

之后在 Service 层即可注入并引用这两个 RedisTemplate ,如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import org.apache.commons.lang3.StringUtils;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Repository;
 
import javax.annotation.Resource;
import java.io.*;
 
@Repository
public class RedisCache {<br>  
    @Resource(name ="cacheRedisTemplate")
    privateRedisTemplate<String, String> cacheRedisTemplate;
 
    publicvoid put(Object key, Object value) {
        if(null== value) {
            return;
        }
 
        if(valueinstanceof String) {
            if(StringUtils.isEmpty(value.toString())) {
                return;
            }
        }
 
        // TODO Auto-generated method stub
        finalString keyf = key + "";
        finalObject valuef = value;
        finallong liveTime = 86400;
 
        cacheRedisTemplate.execute(newRedisCallback<Long>() {
            publicLong doInRedis(RedisConnection connection)
                    throwsDataAccessException {
                byte[] keyb = keyf.getBytes();
                byte[] valueb = toByteArray(valuef);
                connection.set(keyb, valueb);
                if(liveTime > 0) {
                    connection.expire(keyb, liveTime);
                }
                return1L;
            }
        });
    }
 
    publicObject get(Object key) {
        finalString keyf = (String) key;
        Object object;
        object = cacheRedisTemplate.execute(newRedisCallback<Object>() {
            publicObject doInRedis(RedisConnection connection)
                    throwsDataAccessException {
 
                byte[] key = keyf.getBytes();
                byte[] value = connection.get(key);
                if(value == null) {
                    returnnull;
                }
                returntoObject(value);
 
            }
        });
 
        returnobject;
    }
 
    /**
     * 描述 : <byte[]转Object>. <br>
     * <p>
     * <使用方法说明>
     * </p>
     *
     * @param bytes
     * @return
     */
    privateObject toObject(byte[] bytes) {
        Object obj =null;
        try{
            ByteArrayInputStream bis =new ByteArrayInputStream(bytes);
            ObjectInputStream ois =new ObjectInputStream(bis);
            obj = ois.readObject();
            ois.close();
            bis.close();
        }catch (IOException ex) {
            ex.printStackTrace();
        }catch (ClassNotFoundException ex) {
            ex.printStackTrace();
        }
        returnobj;
    }
 
    privatebyte[] toByteArray(Object obj) {
        byte[] bytes =null;
        ByteArrayOutputStream bos =new ByteArrayOutputStream();
        try{
            ObjectOutputStream oos =new ObjectOutputStream(bos);
            oos.writeObject(obj);
            oos.flush();
            bytes = bos.toByteArray();
            oos.close();
            bos.close();
        }catch (IOException ex) {
            ex.printStackTrace();
        }
        returnbytes;
    }
}

最后在 Controller 中调用即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
@Autowired
private RedisCache redisCache;
 
 
@RequestMapping(value ="get", method = RequestMethod.GET)
@ResponseBody
public Object getByMyService(String key) {
    try{
        String result = redisService.get(key);
        returnresult;
    }catch (Exception e) {
        e.printStackTrace();
    }
    returnnull;
}
 
@RequestMapping(value ="save", method = RequestMethod.GET)
@ResponseBody
public Object save() {
    Token token =new Token();
    token.setAccess_token("token");
    token.setExpires_in(1000);
    try{
        redisCache.put("token", token);
    }catch (Exception e) {
        e.printStackTrace();
    }
    return"ok";
}  

操作 Redis 集群

只用 Jedis 自己实现注入(区别于下面的引用spring-data-redis)

把前面的 JedisClusterClient 代码拿过来引用即可,只需实现一个访问 Redis 的 Service ,就可以集成到 Spring mvc 。Service 代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import org.springframework.stereotype.Service;
import util.JedisClusterClient;
 
/**
 * Created by fengdezitai on 2016/10/13.
 */
@Service
public class RedisClusterService {
 
    publicvoid save() throwsException{
        //调用 JedisClusterClient 中的方法
        JedisClusterClient jedisClusterClient = JedisClusterClient.getInstance();
        try{
            jedisClusterClient.SaveRedisCluster();
        }catch(Exception e){
            throwe;
        }
    }
}

最后在 Controller 中调用实现的 Service 即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Controller
@RequestMapping(value ="redisCluster")
public class RedisClusterController {
 
    @Autowired
    privateRedisClusterService redisClusterService;
 
    @RequestMapping(value ="save",method = RequestMethod.GET)
    @ResponseBody
    publicObject save(){
        try{
            redisClusterService.save();
        }catch(Exception e){
            e.printStackTrace();
            returnString.format("error: %s",e.getMessage());
        }
        return"ok";
    }
}  

用 spring-data-redis 包做集成 

Spring 和 spring-data-redis maven 包引用和前面一致,之所以引用 spring-data-redis 1.7.2.RELEASE,是因为目前只有这个最新版本才支持集群操作。

redis 集群服务属性配置

1
2
3
4
redis.maxIdle=300
redis.maxWait=3000
redis.testOnBorrow=false
redis.timeout=3000

spring-data-redis xml 集群配置文件 redis-cluster-context.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
<!-- 连接池 配置 -->
    <beanid="poolConfig"class="redis.clients.jedis.JedisPoolConfig">
        <property name="maxIdle"value="${redis.maxIdle}"/>
        <property name="maxWaitMillis"value="${redis.maxWait}"/>
        <property name="testOnBorrow"value="${redis.testOnBorrow}"/>
    </bean>
 
 
    <beanid="redisClusterConfig"class="org.springframework.data.redis.connection.RedisClusterConfiguration">
        <property name="maxRedirects"value="3"></property>
        <property name="clusterNodes">
            <set>
                <bean class="org.springframework.data.redis.connection.RedisNode">
                    <constructor-arg name="host"value="192.168.31.245"></constructor-arg>
                    <constructor-arg name="port"value="7000"></constructor-arg>
                </bean>
                <bean class="org.springframework.data.redis.connection.RedisNode">
                    <constructor-arg name="host"value="192.168.31.245"></constructor-arg>
                    <constructor-arg name="port"value="7001"></constructor-arg>
                </bean>
                <bean class="org.springframework.data.redis.connection.RedisNode">
                    <constructor-arg name="host"value="192.168.31.245"></constructor-arg>
                    <constructor-arg name="port"value="7002"></constructor-arg>
                </bean>
                 <bean class="org.springframework.data.redis.connection.RedisNode">
                    <constructor-arg name="host"value="192.168.31.210"></constructor-arg>
                    <constructor-arg name="port"value="7003"></constructor-arg>
                </bean>
                <bean class="org.springframework.data.redis.connection.RedisNode">
                    <constructor-arg name="host"value="192.168.31.210"></constructor-arg>
                    <constructor-arg name="port"value="7004"></constructor-arg>
                </bean>
                <bean class="org.springframework.data.redis.connection.RedisNode">
                    <constructor-arg name="host"value="192.168.31.210"></constructor-arg>
                    <constructor-arg name="port"value="7005"></constructor-arg>
                </bean>
            </set>
        </property>
    </bean>
 
    <beanid="redis4CacheConnectionFactory"
          class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
        <constructor-arg name="clusterConfig"ref="redisClusterConfig"/>
        <property name="timeout"value="${redis.timeout}"/>
        <property name="poolConfig"ref="poolConfig"/>
    </bean>
 
 
    <bean name="stringRedisSerializer"class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
    <beanid="clusterRedisTemplate"class="org.springframework.data.redis.core.RedisTemplate">
        <property name="connectionFactory"ref="redis4CacheConnectionFactory"/>
        <property name="keySerializer"ref="stringRedisSerializer"/>
        <property name="hashKeySerializer"ref="stringRedisSerializer"/>
        <property name="valueSerializer"ref="stringRedisSerializer"/>
        <property name="hashValueSerializer"ref="stringRedisSerializer"/>
    </bean>

之后在 Spring 配置文件中引用

1
<importresource="redis-cluster-context.xml"/>

解释以上配置

poolConfig是连接池配置,redisClusterConfig 配置了 Redis 集群的各个节点(节点 host 和 port 最好写在属性配置文件中),集群搭建可见 我的 另一篇博客 。然后下面和单机配置一样了,一对 JedisConnectionFactory 和 RedisTemplate 。

之后在 Service 层即可注入并引用这个 RedisTemplate,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Repository;
 
import java.io.*;
 
/**
 * Created by fengdezitai on 2016/9/29.
 */
@Repository
public class RedisClusterCache {
 
    @Autowired
    privateRedisTemplate clusterRedisTemplate;
 
 
    publicvoid put(Object key, Object value) {
        if(null== value) {
            return;
        }
 
        if(valueinstanceof String) {
            if(StringUtils.isEmpty(value.toString())) {
                return;
            }
        }
 
        // TODO Auto-generated method stub
        finalString keyf = key + "";
        finalObject valuef = value;
        finallong liveTime = 86400;
 
        clusterRedisTemplate.execute(newRedisCallback<Long>() {
            publicLong doInRedis(RedisConnection connection)
                    throwsDataAccessException {
                byte[] keyb = keyf.getBytes();
                byte[] valueb = toByteArray(valuef);
                connection.set(keyb, valueb);
                if(liveTime > 0) {
                    connection.expire(keyb, liveTime);
                }
                return1L;
            }
        });
    }
 
    publicObject get(Object key) {
        finalString keyf = (String) key;
        Object object;
        object = clusterRedisTemplate.execute(newRedisCallback<Object>() {
            publicObject doInRedis(RedisConnection connection)
                    throwsDataAccessException {
 
                byte[] key = keyf.getBytes();
                byte[] value = connection.get(key);
                if(value == null) {
                    returnnull;
                }
                returntoObject(value);
 
            }
        });
 
        returnobject;
    }
 
    /**
     * 描述 : <byte[]转Object>. <br>
     * <p>
     * <使用方法说明>
     * </p>
     *
     * @param bytes
     * @return
     */
    privateObject toObject(byte[] bytes) {
        Object obj =null;
        try{
            ByteArrayInputStream bis =new ByteArrayInputStream(bytes);
            ObjectInputStream ois =new ObjectInputStream(bis);
            obj = ois.readObject();
            ois.close();
            bis.close();
        }catch (IOException ex) {
            ex.printStackTrace();
        }catch (ClassNotFoundException ex) {
            ex.printStackTrace();
        }
        returnobj;
    }
 
    privatebyte[] toByteArray(Object obj) {
        byte[] bytes =null;
        ByteArrayOutputStream bos =new ByteArrayOutputStream();
        try{
            ObjectOutputStream oos =new ObjectOutputStream(bos);
            oos.writeObject(obj);
            oos.flush();
            bytes = bos.toByteArray();
            oos.close();
            bos.close();
        }catch (IOException ex) {
            ex.printStackTrace();
        }
        returnbytes;
    }
}

最后在 Controller 中调用即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@Controller
@RequestMapping(value ="redisCluster")
public class RedisClusterController {
 
    @Autowired
    privateRedisClusterCache redisClusterCache;
 
    @RequestMapping(value ="clusterSave",method = {RequestMethod.GET,RequestMethod.POST})
    @ResponseBody
    publicObject clusterSave(){
        //redisClusterCache.put("cluster","save cluster");
        Token token =new Token();
        token.setExpires_in(1000);
        token.setAccess_token("hello world");
        redisClusterCache.put("token",token);
        return"ok";
    }
 
    @RequestMapping(value ="getKey",method = RequestMethod.GET)
    @ResponseBody
    publicObject getCluster(String key){
        Object val = redisClusterCache.get(key);
        returnval;
    }
} 

注意事项:

  • 版本问题,如果用 spring-data-redis 做集成操作 Reids 集群,只有 spring-data-redis 目前最新版本1.7才包含对集群的操作,而最新的 spring-data-redis 中的某些功能对 Spring mvc 的版本也有些限制,所以尽量选择高版本的 Spring mvc 对应。
  • 如果存储的value值是一个实体对象,那么一定要实现 Serializable 接口
2 0
原创粉丝点击