通过spring注解启用redis缓存

 

一、修改pom文件添加依赖

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

 

二、在java配置类上添加@EnableCaching注解启用注解缓存,类内部声明redis缓存管理器RedisCacheManager,redis缓存管理器依赖RedisTemplate,所以,还要声明Redis连接工厂bean(RedisConnectionFactory)和RedisTemplate bean。

package com.config;

import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;

/**
 * @author : ccf0537
 *      1.在任一config类里使用@EnableCaching注解启用注解驱动的缓存
 *      2.声明缓存管理器,spring内置了很多缓存管理器
 *      3.在需要使用缓存的方法上添加@Cacheable和@CacheEvict
 * @date : 2020/11/25 10:14
 */
@Configuration
@EnableCaching
public class CacheConfig {
    /**
     * 声明缓存管理器,spring提供了如下的缓存管理器,以CaheMange接口类型返回其中一个即可
     *  SimpleCacheManager
     *  NoOpCacheManager
     *  ConcurrentMapCacheManager
     *  CompositeCacheManager
     *  EhCacheCacheManager
     *  RedisCacheManager
     *  GemfireCacheManager
     * @return  CacheManager spring缓存管理器接口
     */
    @Bean
    public CacheManager cacheManager(RedisTemplate redisTemplate){
        System.out.println("declear CacheManager");
        return new RedisCacheManager(redisTemplate);
    }

    /**
     * Redis连接工厂bean
     * @return
     */
    @Bean
    public RedisConnectionFactory redisConnectionFactory(){
        System.out.println("declear RedisConnectionFactory");
        JedisConnectionFactory jcf = new JedisConnectionFactory();
        jcf.setHostName("127.0.0.1");
        jcf.setPort(6379);
        jcf.setPassword("123456");
        return jcf;
    }

    /**
     * RedisTemplate bean
     * @return
     */
    @Bean
    public RedisTemplate<String,String> redisTemplate(){
        System.out.println("declear RedisTemplate");
        RedisConnectionFactory rcf = redisConnectionFactory();
        RedisTemplate<String,String> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(rcf);
        return redisTemplate;
    }

}

 

三、在需要使用缓存的方法上添加@Cacheable注解,通过value属性指定缓存名称,传入方法的参数值是缓存的key,方法的返回值是缓存的value。此时,当方法被外部方法调用时,spring会先根据传入的参数值去缓存里查找,如果找不到对应的值,就调用方法返回结果,并将返回值添加到缓存中,如果找到了,就直接将缓存的值返回,不再调用方法。

注意,当缓存方法被同一个类内的其他方法调用时,只会执行方法,不会触发缓存。这是因为,spring缓存是基于AOP实现的,AOP又是基于代理对象实现的,同类内的方法相互调用不会产生代理对象,所以缓存不会生效。

同样的原因,同一个类内的方法相互调用时,@Transactional注解也会失效,因为spring注解事务也是基于AOP实现的。

@Cacheable(value = "userNameCache")
    public String getUserName(String Id){
        System.out.println("query user from db...");
        return "polly";
    }