为了账号安全,请及时绑定邮箱和手机立即绑定

Spring 整合 Redis

标签:
Spring Redis

pom构建:

<dependency>  
    <groupId>org.springframework.data</groupId>  
    <artifactId>spring-data-redis</artifactId>  
    <version>1.6.0.RELEASE</version>  </dependency>  <dependency>  
    <groupId>org.springframework</groupId>  
    <artifactId>spring-test</artifactId>  
    <version>3.1.2.RELEASE</version>  
    <scope>test</scope>  </dependency><dependency>  
    <groupId>redis.clients</groupId>  
    <artifactId>jedis</artifactId>  
    <version>2.9.0</version>  </dependency>  <dependency>  
    <groupId>junit</groupId>  
    <artifactId>junit</artifactId>  
    <version>4.8.2</version>  
    <scope>test</scope>  </dependency>

spring配置文件(applicationContext.xml):

  <context:property-placeholder location="classpath:redis.properties" />  <!-- redis config start --><!-- 启用缓存注解功能,这个是必须的,否则注解不会生效,另外,该注解一定要声明在spring主配置文件中才会生效 --><cache:annotation-driven cache-manager="cacheManager" /><!-- 配置JedisPoolConfig实例 --><bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
    <property name="maxTotal" value="${redis.maxTotal}" />
    <property name="maxIdle" value="${redis.maxIdle}" />
    <property name="maxWaitMillis" value="${redis.maxWaitMillis}" />
    <property name="testOnBorrow" value="${redis.testOnBorrow}" />
    <property name="testOnReturn" value="${redis.testOnReturn}" />
    <!-- <property name="testWhileIdle" value="true"/> --></bean><!-- 配置JedisConnectionFactory --><bean id="JedisConnectionFactory"
    class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
    p:host-name="${redis.host}" p:port="${redis.port}" p:password="${redis.pass}"
    p:pool-config-ref="jedisPoolConfig" p:timeout="${redis.timeout}" /><!-- 配置RedisTemplate --><bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
    <property name="connectionFactory" ref="JedisConnectionFactory" /></bean><!-- spring自己的缓存管理器,这里定义了缓存位置名称 ,即注解中的value --><bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
    <property name="caches">
        <set>
            <!-- 这里可以配置多个redis -->
            <!-- <bean class="com.cn.util.RedisCache"> <property name="redisTemplate" 
                ref="redisTemplate" /> <property name="name" value="default"/> </bean> -->
            <bean class="com.github.util.RedisCache">
                <property name="redisTemplate" ref="redisTemplate" />
                <property name="name" value="common" />
                <!-- common名称要在类或方法的注解中使用 -->
            </bean>
        </set>
    </property></bean><!-- redis config end -->

开启Spring采用CGLIB代理

<!-- 配置使Spring采用CGLIB代理  --><aop:aspectj-autoproxy proxy-target-class="true" />

redis.properties:

# Redis settingsredis.host=192.168.1.39
redis.port=6379
redis.pass=jay
redis.timeout=0

redis.maxIdle=300
redis.maxTotal=50
redis.maxWaitMillis=1000
redis.testOnBorrow=trueredis.testOnReturn=true

Java代码:
自己实现的缓存类 RedisCache

package com.github.util;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;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;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;
}@Overridepublic String getName() {    return this.name;
}@Overridepublic Object getNativeCache() {    return this.redisTemplate;
}@Overridepublic ValueWrapper get(Object key) {
    System.out.println("get key");    final String keyf = key.toString();
    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);
}@Overridepublic void put(Object key, Object value) {
    System.out.println("put key");    final String keyf = key.toString();    final Object valuef = value;    final long liveTime = 10 * 6;       //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;
        }
    });
}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;
}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;
}@Overridepublic void evict(Object key) {
    System.out.println("del key");    final String keyf = key.toString();
    redisTemplate.execute(new RedisCallback<Long>() {        public Long doInRedis(RedisConnection connection)
                throws DataAccessException {            return connection.del(keyf.getBytes());
        }
    });
}@Overridepublic void clear() {
    System.out.println("clear key");
    redisTemplate.execute(new RedisCallback<String>() {        public String doInRedis(RedisConnection connection)
                throws DataAccessException {
            connection.flushDb();            return "ok";
        }
    });
}@Overridepublic <T> T get(Object key, Class<T> type) {    return null;
}@Overridepublic ValueWrapper putIfAbsent(Object key, Object value) {    return null;
}
}

注意:
spring配置文件中的

<bean class="com.github.util.RedisCache">    <property name="redisTemplate" ref="redisTemplate" />
    <property name="name" value="common" />
    <!-- common名称要在类或方法的注解中使用 --></bean>

name 的value  可以自定义 。后面方法注解的value要和这个对应

对Redis不懂的看这篇文章.

这里配置就完成了。可以直接在service方法上面开启注解:
有4个注解@Cacheable,@CachePut , @CacheEvict,@CacheConfig
@Cacheable、@CachePut、@CacheEvict 注释介绍
@Cacheable 作用和配置方法
@Cacheable 的作用 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存
@Cacheable 主要的参数
value 缓存的名称,在 spring 配置文件中定义,必须指定至少一个例如:这里和上面的name 的value对应,楼主这里写的是common
@Cacheable(value=”mycache”) 或者
@Cacheable(value={”cache1”,”cache2”}
key 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合例如:
@Cacheable(value=”testcache”,key=”#userName”)
condition 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存例如:
@Cacheable(value=”testcache”,condition=”#userName.length()>2”)


--////////////////////////////////////////////////////////////////////////////////

@CachePut 作用和配置方法
@CachePut 的作用 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存,和 @Cacheable 不同的是,它每次都会触发真实方法的调用
@CachePut 主要的参数
value 缓存的名称,在 spring 配置文件中定义,必须指定至少一个例如:
@Cacheable(value=”mycache”) 或者
@Cacheable(value={”cache1”,”cache2”}
key 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合例如:
@Cacheable(value=”testcache”,key=”#userName”)
condition 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存例如:
@Cacheable(value=”testcache”,condition=”#userName.length()>2”)

@CachePut 不同的是不管有没有缓存,都会调用方法.使用于 数据库的插入
//////////////////////////////////////////////////////

@CacheEvict 作用和配置方法
@CachEvict 的作用 主要针对方法配置,能够根据一定的条件对缓存进行清空
@CacheEvict 主要的参数
value 缓存的名称,在 spring 配置文件中定义,必须指定至少一个例如:
@CachEvict(value=”mycache”) 或者
@CachEvict(value={”cache1”,”cache2”}
key 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合例如:
@CachEvict(value=”testcache”,key=”#userName”)
condition 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才清空缓存例如:
@CachEvict(value=”testcache”,
condition=”#userName.length()>2”)
allEntries 是否清空所有缓存内容,缺省为 false,如果指定为 true,则方法调用后将立即清空所有缓存例如:
@CachEvict(value=”testcache”,allEntries=true)
beforeInvocation 是否在方法执行前就清空,缺省为 false,如果指定为 true,则在方法还没有执行的时候就清空缓存,缺省情况下,如果方法执行抛出异常,则不会清空缓存例如:
@CachEvict(value=”testcache”,beforeInvocation=true)

额外补充:
知道你们注意到一个问题没有,就是所有的@Cacheable()里面都有一个value=“xxx”的属性,这显然如果方法多了,写起来也是挺累的,如果可以一次性声明完 那就省事了,
所以,有了@CacheConfig这个配置,@CacheConfig is a class-level annotation that allows to share the cache names,不过不用担心,如果你在你的方法写别的名字,那么依然以方法的名字为准。
注释在类上面
@CacheConfig(cacheNames = "common")



作者:試毅_思伟


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
JAVA开发工程师
手记
粉丝
18
获赞与收藏
121

关注作者,订阅最新文章

阅读免费教程

  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消