一 、配置文件中的内容
- redis 系统配置,即在application.yml文件中的配置
- RedisPoolConfig配置
- RedisPool配置
- RedisConnectionFactory配置
- StringRedisTemplate
- RedisTemplate
package com.seedyee.config;
import java.lang.reflect.Method;
import java.net.UnknownHostException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
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;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectMapper.DefaultTyping;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
/**
* @author lcl
* @createDate 2016年11月22日上午11:00:08 redis 缓存配置类
* 这里实现CachingConfigurerSupport主要是方便使用自定义keyGenerator
*/
@Configuration
@EnableCaching // 启用缓存
public class RedisCacheConfig extends CachingConfigurerSupport {
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private int port;
@Value("${spring.redis.timeout}")
private int timeout;
@Value("${spring.redis.password}")
private String password;
@Value("${spring.redis.pool.max-active}")
private int maxActive;
@Value("${spring.redis.pool.max-wait}")
private int maxWait;
@Value("${spring.redis.pool.max-idle}")
private int maxIdle;
@Value("${spring.redis.pool.min-idle}")
private int mainIdle;
/**
* 配置JedisPoolConfig
* @return JedisPoolConfig实体
*/
@Bean
public JedisPoolConfig jedisPoolConfig() {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxIdle(this.maxIdle);
jedisPoolConfig.setMaxWaitMillis(this.maxWait);
jedisPoolConfig.setMinIdle(this.mainIdle);
return jedisPoolConfig;
}
/**
* 配置JedisPool
* @return
*/
@Bean
public JedisPool jedisPool() {
JedisPool jedisPool = null;
if (this.password != null) {
jedisPool = new JedisPool(this.jedisPoolConfig(), this.host, this.port, this.timeout, this.password);
} else {
jedisPool = new JedisPool(this.jedisPoolConfig(), this.host, this.port);
}
return jedisPool;
}
/**
* RedisConnectionFactory配置
* @return
*/
@Bean
public RedisConnectionFactory redisConnectionFactory() {
return new JedisConnectionFactory(this.jedisPoolConfig());
}
/**
* 配置StringRedisTemplate实体
* @return
*/
@Bean
public StringRedisTemplate stringRedisTemplate() {
StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
stringRedisTemplate.setConnectionFactory(this.redisConnectionFactory());
return stringRedisTemplate;
}
/**
* 配置RedisTemplate
* @return 返回redisTemplate实体
*/
@Bean
public RedisTemplate<String, Object> redisTemplate() throws UnknownHostException {
RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
template.setConnectionFactory(this.redisConnectionFactory());
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(
Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, Visibility.ANY);
om.enableDefaultTyping(DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
//使用StringRedisSerializer作为序列化key,默认是使用JdkSerializationRedisSerializer,会出现脏字段在key中
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
/**
* 自定义keyGenerator
*
* @return
*/
@Bean
public KeyGenerator wiselyKeyGenerator() {
return new KeyGenerator() {
@Override
public Object generate(Object target, Method method, Object... params) {
StringBuffer sb = new StringBuffer();
sb.append("mykey" + ":");
sb.append(method.getName() + ":");
for (Object object : params) {
sb.append(object.toString());
}
return sb.toString();
}
};
}
/**
* 配置redis缓存管理对象
*
* @param redisTemplate
* @return
*/
@Bean(name = "cacheManager")
public CacheManager cacheManager(RedisTemplate<?, ?> redisTemplate) {
return new RedisCacheManager(redisTemplate);
}
}
注意:在配置文件中配置RedisTemplate的之后需要注意,Redis默认使用JdkSerializationRedisSerializer作为序列化key和value的,所以需要重新设置key和value的序列化,本文在代码中采用的key的序列化为StringRedisSerializer
,value的序列化采用jackson2JsonRedisSerializer
,具体代码请查看以上配置文件的代码。如果不设置的话插入redis数据库中的数据的key的形式为:\xAC\xED\x00\x05t\x00\x1810001
,其中10001是自己存的key的值,会多前面这一窜,value的话分为对象和字符串的两种情况,字符串的情况和id的情况是一样的,对象的话就是把属性分为每个字符串的情况。
二、使用
2.1 使用注解实现方法级缓存
可以自定义缓存切入点,可以在dao层做,也可以在service层做,具体可以根据需求,下面记录的是在service层做的:
package com.seedyee.service;
import java.util.Collection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import com.seedyee.dao.EmailDao;
import com.seedyee.dao.RedisDao;
import com.seedyee.dao.UserDao;
import com.seedyee.domain.User;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
/**
* @author lcl
* @createDate 2016年11月21日下午5:30:23
*
*/
@Service
public class UserService {
@Autowired
private CacheManager cacheManager;
@Autowired
private RedisDao redis;
@Autowired
private UserDao userDao;
@Autowired
private EmailDao emailDao;
//@Cacheable(cacheNames = {"users"}, key= "#user.id")
public Object createUser(User user) {
User createUser = null;
createUser = userDao.save(user);
return createUser;
}
@Cacheable(cacheNames = {"users"}, key = "#id" )
public Object getUserInfo(String id) {
User user = null;
user = userDao.findById(id);
Collection<String> cacheNames = cacheManager.getCacheNames();
for (String string : cacheNames) {
System.out.println(string);
System.out.println(cacheManager.getCache(string));
}
System.out.println("--------------进来说明没有使用缓存-------------------");
return user;
}
@CacheEvict(cacheNames = {"users"}, key = "#user.id")
public Object updateUserInfo(User user) {
User formUser = userDao.findById(user.getId());
if (user.getName() != null && formUser != null) {
formUser.setName(user.getName());
//修改成功删除缓存中的数据
//redis.delete(formUser.getId());
return userDao.save(formUser);
}
return "修改出现异常";
}
@CacheEvict(cacheNames = {"users"})
public Object deleteUser(String id) {
userDao.delete(id);
//删除成功删除缓存中的数据
//redis.delete(id);
return "ok";
}
}
2.2 选择在需要的地方存储或是删除缓存的
2.2.1 配置redis对数据库操作类
使用配置文件中配置好的StringRedisTemplate和RedisTemplate来完成对数据库数据的CRUD操作,以下代码主要是存储和删除操作:
文件名 RedisDao.java
package com.seedyee.dao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
/**
* @author lcl
* @createDate 2016年11月24日下午11:03:57
*
*/
@Component
public class RedisDao {
@Autowired
private StringRedisTemplate stringRedisTemplate;
// @Resource(name = "stringRedisTemplate")
// private ValueOperations<String, String> valOpsStr;
@Autowired
private RedisTemplate<String, Object> redisTemplate;
// @Resource
// private ValueOperations<String, Object> valOps;
/**
* 存储字符串
* @param key string类型的key
* @param value String类型的value
*/
public void set(String key, String value) {
stringRedisTemplate.opsForValue().set(key, value);
}
/**
* 存储对象
* @param key String类型的key
* @param value Object类型的value
*/
public void set(String key, Object value) {
redisTemplate.opsForValue().set(key, value);
}
/**
* 根据key获取字符串数据
* @param key
* @return
*/
public String getValue(String key) {
return stringRedisTemplate.opsForValue().get(key);
}
/**
* 根据key获取对象
* @param key
* @return
*/
public Object getValueOfObject(String key) {
return redisTemplate.opsForValue().get(key);
}
/**
* 根据key删除缓存信息
* @param key
*/
public void delete(String key) {
redisTemplate.delete(key);
}
}
2.2.2 对缓存进行操作
在需要对缓存进行操作的地方使用redisDao的示例对象进行操作,下面的代码主要是记录删除时候的操作:
package com.seedyee.service;
import java.util.Collection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import com.seedyee.dao.EmailDao;
import com.seedyee.dao.RedisDao;
import com.seedyee.dao.UserDao;
import com.seedyee.domain.User;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
/**
* @author lcl
* @createDate 2016年11月21日下午5:30:23
*
*/
@Service
public class UserService {
@Autowired
private CacheManager cacheManager;
@Autowired
private RedisDao redis;
@Autowired
private UserDao userDao;
@Autowired
private EmailDao emailDao;
//@Cacheable(cacheNames = {"users"}, key= "#user.id")
public Object createUser(User user) {
User createUser = null;
createUser = userDao.save(user);
return createUser;
}
@Cacheable(cacheNames = {"users"}, key = "#id" )
public Object getUserInfo(String id) {
User user = null;
user = userDao.findById(id);
Collection<String> cacheNames = cacheManager.getCacheNames();
for (String string : cacheNames) {
System.out.println(string);
System.out.println(cacheManager.getCache(string));
}
System.out.println("--------------进来说明没有使用缓存-------------------");
return user;
}
//@CacheEvict(cacheNames = {"users"}, key = "#user.id")
public Object updateUserInfo(User user) {
User formUser = userDao.findById(user.getId());
if (user.getName() != null && formUser != null) {
formUser.setName(user.getName());
//修改成功删除缓存中的数据
redis.delete(formUser.getId());
return userDao.save(formUser);
}
return "修改出现异常";
}
//@CacheEvict(cacheNames = {"users"})
public Object deleteUser(String id) {
userDao.delete(id);
//删除成功删除缓存中的数据
*redis.delete(id);*
return "ok";
}
}
注意:在使用第二种方法实现缓存的时候,上面代码中删除缓存对应的信息以后,cacheName下的key的值没有删掉,cacheName下存储同一类的不同key。这里记录一下,寻求解决方法中。。。