通过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";
}