spring+redis(redis当cache使用)
2016-10-28 18:15
399 查看
1.导入相应的jar包
2.redis.properties
#ip
redis.host=127.0.0.1
#端口
redis.port=6379
#密码
redis.pass=test
redis.maxIdle=300
redis.maxActive=600
redis.maxWait=1000
redis.testOnBorrow=true
redis.timeout=1000
##最大连接数:能够同时建立的“最大链接个数”
#redis.pool.maxActive=200
##最大空闲数:空闲链接数大于maxIdle时,将进行回收
#redis.pool.maxIdle=20
##最小空闲数:低于minIdle时,将创建新的链接
#redis.pool.minIdle=5
##最大等待时间:单位ms
#redis.pool.maxWait=3000
##使用连接时,检测连接是否成功
#redis.pool.testOnBorrow=true
#返回连接时,检测连接是否成功
redis.pool.testOnReturn=true
3.spring_redis.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:oxm="http://www.springframework.org/schema/oxm" xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:task="http://www.springframework.org/schema/task"
xmlns:cache="http://www.springframework.org/schema/cache" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache.xsd">
<!---开启缓存注解->
<cache:annotation-driven />
<!--redis连接池-->
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxIdle" value="${redis.maxIdle}" />
<!-- <property name="maxActive" value="${redis.maxActive}" /> -->
<!-- <property name="maxWait" value="${redis.maxWait}" /> -->
<!-- 上面这两个是老版本的属性 -->
<property name="maxTotal" value="${redis.maxActive}" />
<property name="maxWaitMillis" value="${redis.maxWait}"></property>
<property name="testOnBorrow" value="${redis.testOnBorrow}" />
</bean>
<!--连接redis数据库的参数-->
<bean id="connectionFactory" 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="poolConfig"/>
<!--redis模板-->
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="connectionFactory" />
<property name="enableTransactionSupport" value="true" />
<!--key使用String序列化-->
<property name="keySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
<!--value使用json序列化。主要是保存对象时,用其他序列化,在数据库显示的是/XDFF/***这种序列化的样式-->
<!--这里只用到了redis String一种的数据结构,其他hash,set等都没用到-->
<property name="valueSerializer">
<!-- <bean class="org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer" /> -->
<!--这个自定义的json序列类,参考了一下博客-->
<!--http://blog.csdn.net/neosmith/article/details/46800235-->
<bean class="com.zhshch.cache.MyJacksonSerializer" />
</property>
</bean>
<!--初始化缓存管理器-->
<bean id="cacheManager" class="org.springframework.data.redis.cache.RedisCacheManager">
<constructor-arg ref="redisTemplate" />
</bean>
</beans>
在使用缓存的时候,一定要定义缓存管理器为id="cacheManager"
定义其他名字,服务器已启动就报找不到cacheManager,应该是spring缓存内置需要这个bean
@Autowired
private RedisCacheManager cacheManager ;(如果需要这个管理器,这么使用)
package com.zhshch.cache;
import java.io.IOException;
import org.codehaus.jackson.annotate.JsonTypeInfo;
import org.codehaus.jackson.annotate.JsonTypeInfo.As;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.ObjectMapper.DefaultTyping;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import com.fasterxml.jackson.databind.ser.SerializerFactory;
public class MyJacksonSerializer implements RedisSerializer<Object> {
private final ObjectMapper mapper;
/**
* Creates {@link GenericJackson2JsonRedisSerializer} and configures {@link ObjectMapper} for default typing.
*/
public MyJacksonSerializer() {
this((String) null);
}
/**
* Creates {@link GenericJackson2JsonRedisSerializer} and configures {@link ObjectMapper} for default typing using the
* given {@literal name}. In case of an {@literal empty} or {@literal null} String the default
* {@link JsonTypeInfo.Id#CLASS} will be used.
*
* @param classPropertyTypeName Name of the JSON property holding type information. Can be {@literal null}.
*/
public MyJacksonSerializer(String classPropertyTypeName) {
this(new ObjectMapper());
if (StringUtils.hasText(classPropertyTypeName)) {
mapper.enableDefaultTypingAsProperty(DefaultTyping.NON_FINAL, classPropertyTypeName);
} else {
mapper.enableDefaultTyping(DefaultTyping.NON_FINAL, As.PROPERTY);
}
}
/**
* Setting a custom-configured {@link ObjectMapper} is one way to take further control of the JSON serialization
* process. For example, an extended {@link SerializerFactory} can be configured that provides custom serializers for
* specific types.
*
* @param mapper must not be {@literal null}.
*/
public MyJacksonSerializer(ObjectMapper mapper) {
Assert.notNull(mapper, "ObjectMapper must not be null!");
this.mapper = mapper;
}
public byte[] serialize(Object t) throws SerializationException {
byte[] returnByte = null;
if (t == null) {
returnByte = new byte[0];
}else{
try {
returnByte = mapper.writeValueAsBytes(t);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return returnByte ;
}
public Object deserialize(byte[] bytes) throws SerializationException {
return deserialize(bytes, Object.class);
}
/**
* @param source can be {@literal null}.
* @param type must not be {@literal null}.
* @return {@literal null} for empty source.
* @throws SerializationException
*/
public <T> T deserialize(byte[] source, Class<T> type) throws SerializationException {
Assert.notNull(type,
"Deserialization type must not be null! Pleaes provide Object.class to make use of Jackson2 default typing.");
if (StringUtils.isEmpty(source)) {
return null;
}
try {
return mapper.readValue(source, type);
} catch (Exception ex) {
throw new SerializationException("Could not read JSON: " + ex.getMessage(), ex);
}
}
}
具体缓存的使用
@Service("cacheService")
@CacheConfig(cacheNames={"baseCache"})
public class CacheService implements ICacheService {
//代替数据库
private static Map<String,Object> map = new HashMap<String,Object>();
static{
Person p = new Person();
p.setId("1");
p.setName("周星驰");
p.setAge(22);
map.put("1", p);
}
@CachePut(key="#id")
public Person testCachePut(String id, Person person) {
return person ;
}
@CacheEvict(key="#person.id")
public String testCacheEvict(String id, Person person) {
map.remove(id) ;
return "success" ;
}
@Cacheable(key="#p0")
public Person testCacheable(String id, Person person) {
System.out.println("缓存不存在,查询数据库");
return (Person)map.get(id) ;
}
public Person getPerson(){
Person person = new Person();
person.setId("1");
person.setName("刘德华");
person.setAge(33);
return person ;
}
@Cacheable(key ="#key")
public List<Person> testCacheableList(String key) {
List<Person> list = new ArrayList<Person>();
Person person1 = getPerson();
Person person2 = getPerson();
list.add(person1) ;
list.add(person2) ;
return list ;
}
}
测试testCacheableList的时候,redis管理软件看到数据结构是这种形式
如果需要自定义的redis缓存
缓存管理bean可以这么写
<!-- <bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager"> -->
<!-- <property name="caches"> -->
<!-- <set> -->
<!-- <bean class="com.zhshch.cache.MyRedisCache"> -->
<!-- <property name="redisTemplate" ref="redisTemplate" /> -->
<!-- <property name="name" value="baseCache" /> -->
<!-- </bean> -->
<!-- </set> -->
<!-- </property> -->
<!-- </bean> -->
然后
public class MyRedisCache implements Cache{
private RedisTemplate redisTemplate ;
private String name ;
public RedisTemplate getRedisTemplate() {
return redisTemplate;
}
public void setRedisTemplate(RedisTemplate redisTemplate) {
this.redisTemplate = redisTemplate;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name ;
}
使用redisTemplate实现cache的put get操作就行
类似下面
public ValueWrapper get(final Object key) {
ValueWrapper returnValue = null ;
Map map = redisTemplate.opsForHash().entries(key);
// Object obj = redisTemplate.execute(new RedisCallback<Object>() {
// public Object doInRedis(RedisConnection connection) throws DataAccessException {
// byte[] bKey = redisTemplate.getStringSerializer().serialize(key) ;
// byte[] bValue = connection.get(bKey) ;
// return redisTemplate.getHashValueSerializer().deserialize(bValue) ;
// }
// }) ;
// if(!StringUtils.isEmpty(obj)){
returnValue = new SimpleValueWrapper(map);
// }
return returnValue;
}
2.redis.properties
#ip
redis.host=127.0.0.1
#端口
redis.port=6379
#密码
redis.pass=test
redis.maxIdle=300
redis.maxActive=600
redis.maxWait=1000
redis.testOnBorrow=true
redis.timeout=1000
##最大连接数:能够同时建立的“最大链接个数”
#redis.pool.maxActive=200
##最大空闲数:空闲链接数大于maxIdle时,将进行回收
#redis.pool.maxIdle=20
##最小空闲数:低于minIdle时,将创建新的链接
#redis.pool.minIdle=5
##最大等待时间:单位ms
#redis.pool.maxWait=3000
##使用连接时,检测连接是否成功
#redis.pool.testOnBorrow=true
#返回连接时,检测连接是否成功
redis.pool.testOnReturn=true
3.spring_redis.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:oxm="http://www.springframework.org/schema/oxm" xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:task="http://www.springframework.org/schema/task"
xmlns:cache="http://www.springframework.org/schema/cache" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache.xsd">
<!---开启缓存注解->
<cache:annotation-driven />
<!--redis连接池-->
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxIdle" value="${redis.maxIdle}" />
<!-- <property name="maxActive" value="${redis.maxActive}" /> -->
<!-- <property name="maxWait" value="${redis.maxWait}" /> -->
<!-- 上面这两个是老版本的属性 -->
<property name="maxTotal" value="${redis.maxActive}" />
<property name="maxWaitMillis" value="${redis.maxWait}"></property>
<property name="testOnBorrow" value="${redis.testOnBorrow}" />
</bean>
<!--连接redis数据库的参数-->
<bean id="connectionFactory" 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="poolConfig"/>
<!--redis模板-->
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="connectionFactory" />
<property name="enableTransactionSupport" value="true" />
<!--key使用String序列化-->
<property name="keySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
<!--value使用json序列化。主要是保存对象时,用其他序列化,在数据库显示的是/XDFF/***这种序列化的样式-->
<!--这里只用到了redis String一种的数据结构,其他hash,set等都没用到-->
<property name="valueSerializer">
<!-- <bean class="org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer" /> -->
<!--这个自定义的json序列类,参考了一下博客-->
<!--http://blog.csdn.net/neosmith/article/details/46800235-->
<bean class="com.zhshch.cache.MyJacksonSerializer" />
</property>
</bean>
<!--初始化缓存管理器-->
<bean id="cacheManager" class="org.springframework.data.redis.cache.RedisCacheManager">
<constructor-arg ref="redisTemplate" />
</bean>
</beans>
在使用缓存的时候,一定要定义缓存管理器为id="cacheManager"
定义其他名字,服务器已启动就报找不到cacheManager,应该是spring缓存内置需要这个bean
@Autowired
private RedisCacheManager cacheManager ;(如果需要这个管理器,这么使用)
package com.zhshch.cache;
import java.io.IOException;
import org.codehaus.jackson.annotate.JsonTypeInfo;
import org.codehaus.jackson.annotate.JsonTypeInfo.As;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.ObjectMapper.DefaultTyping;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import com.fasterxml.jackson.databind.ser.SerializerFactory;
public class MyJacksonSerializer implements RedisSerializer<Object> {
private final ObjectMapper mapper;
/**
* Creates {@link GenericJackson2JsonRedisSerializer} and configures {@link ObjectMapper} for default typing.
*/
public MyJacksonSerializer() {
this((String) null);
}
/**
* Creates {@link GenericJackson2JsonRedisSerializer} and configures {@link ObjectMapper} for default typing using the
* given {@literal name}. In case of an {@literal empty} or {@literal null} String the default
* {@link JsonTypeInfo.Id#CLASS} will be used.
*
* @param classPropertyTypeName Name of the JSON property holding type information. Can be {@literal null}.
*/
public MyJacksonSerializer(String classPropertyTypeName) {
this(new ObjectMapper());
if (StringUtils.hasText(classPropertyTypeName)) {
mapper.enableDefaultTypingAsProperty(DefaultTyping.NON_FINAL, classPropertyTypeName);
} else {
mapper.enableDefaultTyping(DefaultTyping.NON_FINAL, As.PROPERTY);
}
}
/**
* Setting a custom-configured {@link ObjectMapper} is one way to take further control of the JSON serialization
* process. For example, an extended {@link SerializerFactory} can be configured that provides custom serializers for
* specific types.
*
* @param mapper must not be {@literal null}.
*/
public MyJacksonSerializer(ObjectMapper mapper) {
Assert.notNull(mapper, "ObjectMapper must not be null!");
this.mapper = mapper;
}
public byte[] serialize(Object t) throws SerializationException {
byte[] returnByte = null;
if (t == null) {
returnByte = new byte[0];
}else{
try {
returnByte = mapper.writeValueAsBytes(t);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return returnByte ;
}
public Object deserialize(byte[] bytes) throws SerializationException {
return deserialize(bytes, Object.class);
}
/**
* @param source can be {@literal null}.
* @param type must not be {@literal null}.
* @return {@literal null} for empty source.
* @throws SerializationException
*/
public <T> T deserialize(byte[] source, Class<T> type) throws SerializationException {
Assert.notNull(type,
"Deserialization type must not be null! Pleaes provide Object.class to make use of Jackson2 default typing.");
if (StringUtils.isEmpty(source)) {
return null;
}
try {
return mapper.readValue(source, type);
} catch (Exception ex) {
throw new SerializationException("Could not read JSON: " + ex.getMessage(), ex);
}
}
}
具体缓存的使用
@Service("cacheService")
@CacheConfig(cacheNames={"baseCache"})
public class CacheService implements ICacheService {
//代替数据库
private static Map<String,Object> map = new HashMap<String,Object>();
static{
Person p = new Person();
p.setId("1");
p.setName("周星驰");
p.setAge(22);
map.put("1", p);
}
@CachePut(key="#id")
public Person testCachePut(String id, Person person) {
return person ;
}
@CacheEvict(key="#person.id")
public String testCacheEvict(String id, Person person) {
map.remove(id) ;
return "success" ;
}
@Cacheable(key="#p0")
public Person testCacheable(String id, Person person) {
System.out.println("缓存不存在,查询数据库");
return (Person)map.get(id) ;
}
public Person getPerson(){
Person person = new Person();
person.setId("1");
person.setName("刘德华");
person.setAge(33);
return person ;
}
@Cacheable(key ="#key")
public List<Person> testCacheableList(String key) {
List<Person> list = new ArrayList<Person>();
Person person1 = getPerson();
Person person2 = getPerson();
list.add(person1) ;
list.add(person2) ;
return list ;
}
}
测试testCacheableList的时候,redis管理软件看到数据结构是这种形式
如果需要自定义的redis缓存
缓存管理bean可以这么写
<!-- <bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager"> -->
<!-- <property name="caches"> -->
<!-- <set> -->
<!-- <bean class="com.zhshch.cache.MyRedisCache"> -->
<!-- <property name="redisTemplate" ref="redisTemplate" /> -->
<!-- <property name="name" value="baseCache" /> -->
<!-- </bean> -->
<!-- </set> -->
<!-- </property> -->
<!-- </bean> -->
然后
public class MyRedisCache implements Cache{
private RedisTemplate redisTemplate ;
private String name ;
public RedisTemplate getRedisTemplate() {
return redisTemplate;
}
public void setRedisTemplate(RedisTemplate redisTemplate) {
this.redisTemplate = redisTemplate;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name ;
}
使用redisTemplate实现cache的put get操作就行
类似下面
public ValueWrapper get(final Object key) {
ValueWrapper returnValue = null ;
Map map = redisTemplate.opsForHash().entries(key);
// Object obj = redisTemplate.execute(new RedisCallback<Object>() {
// public Object doInRedis(RedisConnection connection) throws DataAccessException {
// byte[] bKey = redisTemplate.getStringSerializer().serialize(key) ;
// byte[] bValue = connection.get(bKey) ;
// return redisTemplate.getHashValueSerializer().deserialize(bValue) ;
// }
// }) ;
// if(!StringUtils.isEmpty(obj)){
returnValue = new SimpleValueWrapper(map);
// }
return returnValue;
}
相关文章推荐
- spring redis cache使用思考
- spring boot 整合 redis,使用@Cacheable,@CacheEvict,@CachePut,jedisPool操作redis数据库
- 在 spring boot 中使用spring cache + redis
- SpringBoot使用Redis做缓存,@Cacheable、@CachePut、@CacheEvict等注解的使用
- 【redis】5.spring boot项目中,直接在spring data jpa的Repository层使用redis +redis注解@Cacheable直接在Repository层使用,报错问题处理Null key returned for cache operation
- spring4集成redis 并使用@cacheable注解
- Spring-Boot (四) cache/ehcache/redis-cache集成使用
- SpringBank 开发日志 Mybatis 使用redis 作为二级缓存时,无法通过cacheEnabled=false 将其关闭
- spring-data-redis使用RedisTemplate模板存储时键值与预设不一致的解决方法
- spring 注解配置使用id @Qualifier("flightCacheManager")
- jedis与spring整合及简单的使用RedisTemplate操作
- Spring使用Cache、整合Ehcache
- spring data redis使用示例
- 使用spring-session把http session放到redis里面
- 使用spring3.0的cache方案解决缓存问题
- 【Redis基础】SSH 中Spring-data-redis使用体验
- 在spring data jpa中使用redis的通用list及entity存储方法
- spring-data-redis使用自定义序列化数据 使用 protobuf
- Django使用redis做cache
- Spring 3.1 中使用 @Cacheable