Spring整合Redis注解实现

之前我们说了Spring这个Redis,使用RedisTemplate 实现,不过有些地方也过于麻烦,因此Spring 团队对 Jedis 进行了封装,独立为 spring-data-redis 项目,配合 spring 特性并集成 Jedis 的一些命令和方法。并提供了相关注解,帮助我们快速开发,实现缓存功能

1. 添加项目依赖

<!--redis 缓存-->
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-redis</artifactId>
            <version>1.8.4.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.9.0</version>
        </dependency>

2.修改spring配置文件

注意:注解的缓存实现需要比Spring方式多配置一个cacheManager

<!-- jedis 配置 -->

    <!-- redis连接池的配置 -->
    <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <property name="maxTotal" value="100" />
        <property name="maxIdle" value="${redis.maxIdle}"/>
        <property name="minIdle" value="${redis.minIdle}"/>
        <property name="maxWaitMillis" value="${redis.maxWaitMillis}"/>
        <property name="testOnBorrow" value="${redis.testOnBorrow}"/>
        <property name="testOnReturn" value="${redis.testOnReturn}"/>
    </bean>

    <!-- redis的连接池pool,不是必选项:timeout/password  -->
    <bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" >
        <property name="usePool" value="true"></property>
        <property name="hostName" value="${redis.host}" />
        <property name="port" value="${redis.port}" />
        <property name="password" value="${redis.password}" />
        <property name="timeout" value="100000" />
        <property name="database" value="0"></property>
        <constructor-arg index="0" ref="jedisPoolConfig" />
    </bean>

  <!-- 配置redis模板,需要注入到 RedisCacheManager by dada -->
    <bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">
        <property name="connectionFactory"   ref="connectionFactory" />
        <property name="keySerializer">
            <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
            </property>
        <property name="valueSerializer">
            <bean  class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />
        </property>
    </bean>

    <!-- 配置缓存 by dada -->
    <bean id="cacheManager" class="org.springframework.data.redis.cache.RedisCacheManager">
        <constructor-arg ref="redisTemplate" />
        <!--<property name="defaultExpiration" value="300"></property>-->
        <property name="usePrefix" value="true"></property>
        <property name="expires">
            <util:map>
                <!-- 指定key的时间为1500秒 --> 
                <entry key="get_news_notices_list" value="1500"></entry>
                <entry key="get_areas_bypid_list" value="1500"></entry>
            </util:map>
        </property>
    </bean>

由于使用的是spring提供的注解方式实现redis缓存,所以需要在spring配置文件加上cache标签,否则注解不会生效。如果注解是使用在Controller层,需要SpringMVC配置文件也要加上

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

3.注解介绍

  1. @CacheConfig 配置在类上,cacheNames即定义了本类中所有用到缓存的地方,都去找这个库。只要使用了这个注解,在方法上@Cacheable @CachePut @CacheEvict就可以不用写value去找具体库名了。【一般不怎么用】
  2. @Cacheable 配置在方法或类上,作用:本方法执行后,先去缓存看有没有数据,如果没有,从数据库中查找出来,给缓存中存一份,返回结果会将方法的返回值作为value进行缓存,下次本方法执行,在缓存未过期情况下,先在缓存中查找,有的话直接返回,没有的话从数据库查找
  3. @CachePut 类似于更新操作,即每次不管缓存中有没有结果,都从数据库查找结果,并将结果更新到缓存,并返回结果
  4. @CacheEvict 用来清除用在本方法或者类上的缓存数据(用在哪里清除哪里)

总结

  1. 我们在类上使用了@CacheConfig 注解,则相当于声明缓存到哪个数据库,则下面的方法中使用@Cacheable 则不需要使用value 属性.
  2. @Cacheable 中使用key 属性指定我们redis的key值,支持SPEL 表达式,也就是我们可以使用方法的参数来当做key,同样Spring团队Spring还为我们提供了一个root对象可以用来生成key。通过该root对象我们可以获取到以下信息。
属性名称描述示例
methodName当前方法名#root.methodName
method当前方法#root.method.name
target当前被调用的对象#root.target
targetClass当前被调用的对象的class#root.targetClass
args当前方法参数组成的数组#root.args[0]
caches当前被调用的方法使用的Cache#root.caches[0].name

同样如果我们没有在@Cacheable 中指定key的属性,则会使用默认我们自定义的key生成规则

在我们的redis配置文件中增加配置

 <!-- 配置RedisCacheConfig -->
    <bean id="redisCacheConfig" class="com.yz.redis.RedisCacheConfig">
        <constructor-arg ref="connectionFactory"/>
        <constructor-arg ref="redisTemplate"/>
        <constructor-arg ref="cacheManager"/>
    </bean>
@Configuration
@EnableCaching
public class RedisCacheConfig extends CachingConfigurerSupport {
    protected final static Logger log = LoggerFactory.getLogger(RedisCacheConfig.class);

    private volatile JedisConnectionFactory mJedisConnectionFactory;
    private volatile RedisTemplate<String, String> mRedisTemplate;
    private volatile RedisCacheManager mRedisCacheManager;

    public RedisCacheConfig() {
        super();
    }

    public RedisCacheConfig(JedisConnectionFactory mJedisConnectionFactory, RedisTemplate<String, String> mRedisTemplate, RedisCacheManager mRedisCacheManager) {
        super();
        this.mJedisConnectionFactory = mJedisConnectionFactory;
        this.mRedisTemplate = mRedisTemplate;
        this.mRedisCacheManager = mRedisCacheManager;
    }

    public JedisConnectionFactory redisConnectionFactory() {
        return mJedisConnectionFactory;
    }

    public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory cf) {
        return mRedisTemplate;
    }

    public CacheManager cacheManager(RedisTemplate<?, ?> redisTemplate) {
        return mRedisCacheManager;
    }

    @Bean
    public KeyGenerator keyGenerator() {
        return new KeyGenerator() {
            @Override
            public Object generate(Object o, Method method, Object... objects) {
                StringBuilder sb = new StringBuilder();
                sb.append(o.getClass().getName());
                sb.append(method.getName());
                for (Object obj : objects) {
                    sb.append(obj.toString());
                }
                return sb.toString();
            }
        };
    }
}

该配置类继承自 org.springframework.cache.annotation.CachingConfigurerSupport 并实现 org.springframework.cache.annotation.CachingConfigurer 的方法。

4.示例

    @Cacheable(value = "get_news_notices_list",key = "'newsNotice'+#userNo.concat(#typeSn)")
	@ResponseBody
	@RequestMapping("/ajaxListVo")
	public String ajaxListVo(NewsNotice notice, Query query,String typeSn,HttpServletRequest request, HttpServletResponse response,String userNo) {
		//业务逻辑


我们声明缓存的数据库为get_news_notices_list,并需要在配置文件中指定以及过期时间

<entry key="get_news_notices_list" value="1500"></entry>

缓存的key使用SPEL表达式对参数进行取值'newsNotice'+#userNo.concat(#typeSn)为字符串newsNotice加上我们参数userNo以及typeSn

首先我们的数据库中缓存是没有的
在这里插入图片描述

当我们访问接口的时候,发现缓存中没有相关的key,于是访问数据库,并将方法结果缓存到redis
此时我们使用monitor 命令监控,发现数据确实缓存到redis服务器中了
在这里插入图片描述

当我们再次访问接口的时候,已经是从缓存拿数据了~~

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值