我是靠谱客的博主 义气犀牛,最近开发中收集的这篇文章主要介绍架构之路之spring集成redis缓存1.前言2.redis特点和优势3.依赖4.集成5.测试,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

1.前言

     上篇文章,我们使用了spring自带的缓存机制cache,简单便捷,但同时又存在一定局限性,比如缓存大小扩展,过期时间设置,分布式缓存共享等,这篇文章我们就集成redis,使用redis来做spring的缓存。

2.redis特点和优势

2.1 redis的特点:

(1)Redis数据库完全在内存中,使用磁盘仅用于持久性。
(2)相比许多键值数据存储,Redis拥有一套较为丰富的数据类型。
(3)Redis可以将数据复制到任意数量的从服务器。

2.2 redis的优势:

(1)异常快速:Redis的速度非常快,每秒能执行约11万集合,每秒约81000+条记录。
(2)支持丰富的数据类型:Redis支持最大多数开发人员已经知道像列表,集合,有序集合,散列数据类型。这使得它非常容易解决各种各样的问题,因为我们知道哪些问题是可以处理通过它的数据类型更好。
(3)操作都是原子性:所有Redis操作是原子的,这保证了如果两个客户端同时访问的Redis服务器将获得更新后的值。
(4)多功能实用工具:Redis是一个多实用的工具,可以在多个用例如缓存,消息,队列使用(Redis原生支持发布/订阅),任何短暂的数据,应用程序,如Web应用程序会话,网页命中计数等。

3.依赖

<dependency>  
            <groupId>org.springframework.data</groupId>  
            <artifactId>spring-data-redis</artifactId>  
            <version>1.7.2.RELEASE</version>  
        </dependency>  
        <dependency>  
            <groupId>redis.clients</groupId>  
            <artifactId>jedis</artifactId>  
            <version>2.8.1</version>  
        </dependency>

4.集成

4.1 重写Cache方法

RedisCache:

package com.tl.skyLine.cache;

import org.springframework.cache.Cache;
import org.springframework.cache.support.SimpleValueWrapper;
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 java.io.*;

/**
 * Created by tl on 17/2/28.
 */
public class RedisCache implements Cache {

    private RedisTemplate<String, Object> redisTemplate;
    private String name;

    public RedisTemplate<String, Object> getRedisTemplate() {
        return redisTemplate;
    }

    public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String getName() {
        return this.name;
    }

    @Override
    public Object getNativeCache() {
        return this.redisTemplate;
    }

    @Override
    public ValueWrapper get(Object key) {
        final String keyf = (String) key;
        Object object = null;
        object = redisTemplate.execute(new RedisCallback<Object>() {
            public Object doInRedis(RedisConnection connection) throws DataAccessException {

                byte[] key = keyf.getBytes();
                byte[] value = connection.get(key);
                if (value == null) {
                    return null;
                }
                return toObject(value);
            }
        });
        return (object != null ? new SimpleValueWrapper(object) : null);
    }

    @Override
    public void put(Object key, Object value) {
        final String keyf = (String) key;
        final Object valuef = value;
        final long liveTime = 86400;

        redisTemplate.execute(new RedisCallback<Long>() {
            public Long doInRedis(RedisConnection connection) throws DataAccessException {
                byte[] keyb = keyf.getBytes();
                byte[] valueb = toByteArray(valuef);
                connection.set(keyb, valueb);
                if (liveTime > 0) {
                    connection.expire(keyb, liveTime);
                }
                return 1L;
            }
        });
    }

    /**
     * 描述 : <Object转byte[]>. <br>
     * <p>
     * <使用方法说明>
     * </p>
     *
     * @param obj
     * @return
     */
    private byte[] 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();
        }
        return bytes;
    }

    /**
     * 描述 : <byte[]转Object>. <br>
     * <p>
     * <使用方法说明>
     * </p>
     *
     * @param bytes
     * @return
     */
    private Object 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();
        }
        return obj;
    }

    @Override
    public void evict(Object key) {
        final String keyf = (String) key;
        redisTemplate.execute(new RedisCallback<Long>() {
            public Long doInRedis(RedisConnection connection) throws DataAccessException {
                return connection.del(keyf.getBytes());
            }
        });
    }

    @Override
    public void clear() {
        redisTemplate.execute(new RedisCallback<String>() {
            public String doInRedis(RedisConnection connection) throws DataAccessException {
                connection.flushDb();
                return "ok";
            }
        });
    }

    @SuppressWarnings("unchecked")
    @Override
    public <T> T get(Object key, Class<T> type) {
        final String keyf = (String) key;
        Object object = null;
        object = redisTemplate.execute(new RedisCallback<Object>() {
            public Object doInRedis(RedisConnection connection) throws DataAccessException {

                byte[] key = keyf.getBytes();
                byte[] value = connection.get(key);
                if (value == null) {
                    return null;
                }
                return toObject(value);
            }
        });
        return (T) object;
    }

    @Override
    public ValueWrapper putIfAbsent(Object key, Object value) {
        put(key, value);
        return new SimpleValueWrapper(value);
    }
}

4.2 修改配置文件

将spring-contex.xml配置文件中的

<!-- 启用缓存注解功能,这个是必须的,否则注解不会生效,另外,该注解一定要声明在spring主配置文件中才会生效 -->  
    <cache:annotation-driven cache-manager="scacheManager"/>  
  
    <!--为了区别shiro中引用的id="cacheManager"-->  
    <bean id="scacheManager" class="org.springframework.cache.support.SimpleCacheManager">  
        <property name="caches">  
            <set>  
                <!--这边我们使用的是spring默认的缓存bean,我们也可以根据实际情况进行自定义-->  
                <bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="default"/>  
                <bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="skyCache"/>  
            </set>  
        </property>  
    </bean>

修改为:

<!-- 启用缓存注解功能,这个是必须的,否则注解不会生效,另外,该注解一定要声明在spring主配置文件中才会生效 -->
    <cache:annotation-driven cache-manager="scacheManager"/>

    <!--为了区别shiro中引用的id="cacheManager"-->
    <bean id="scacheManager" class="org.springframework.cache.support.SimpleCacheManager">
        <property name="caches">
            <set>
                <bean class="com.tl.skyLine.cache.RedisCache">
                    <property name="redisTemplate" ref="redisTemplate"/>
                    <property name="name" value="skyCache"/>
                </bean>
            </set>
        </property>
    </bean>

redis-contex.xml配置文件参照之前的文章 点击打开链接

UserDaoImpl注解内容不做修改:

 @Override
//    value是必选项,定义了使用的缓存集合,key如果不定义时默认为方法的参数.key采用的是SpEL表达式
    @Cacheable(value = "skyCache", key = "#username")
    public User findOneByUsername(String username) {
        Query query = new Query();
        Criteria criteria = Criteria.where("username").is(username);
        query.addCriteria(criteria);
        return this.mongoTemplate.findOne(query, User.class);
    }

5.测试

 @Test
    public void findOneByUsername() {
        User use = userDao.findOneByUsername("skyLine");
    }

在redis客户端查看key:


use对象就被保存在redis中!

最后

以上就是义气犀牛为你收集整理的架构之路之spring集成redis缓存1.前言2.redis特点和优势3.依赖4.集成5.测试的全部内容,希望文章能够帮你解决架构之路之spring集成redis缓存1.前言2.redis特点和优势3.依赖4.集成5.测试所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(75)

评论列表共有 0 条评论

立即
投稿
返回
顶部