基于spring的cache基本配置与使用
spring的配置文件:
<!-- redis配置 -->
<bean id="sysConfigJedisConnFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
p:use-pool="true">
<property name="poolConfig" ref="jedisPoolConfig" />
<property name="hostName" value="${redis.machine.ip}" />
<property name="port" value="${redis.machine.port}" />
</bean>
<bean id="sysConfigRedisTemplate" class="org.springframework.data.redis.core.RedisTemplate" p:connection-factory-ref="sysConfigJedisConnFactory" />
<!-- 配置使用缓存 -->
<bean
class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean"
id="com.leo.util.Constants.SYSCONFIG_CACHE_IN_REDIS" />
<bean id="sysConfigCacheManager" class="org.springframework.cache.support.SimpleCacheManager">
<property name="caches">
<set>
<!-- 自定义类(实现cache接口) -->
<bean class="com.leo.system.cache.SysConfigSimpleRedisCache"
p:name-ref="com.leo.util.Constants.SYSCONFIG_CACHE_IN_REDIS" />
</set>
</property>
</bean>
自定义一个类实现spring包下的cache接口,cache注解主要是根据相应的实现方法去执行相应的操作
比如@CacheEvict注解式会执行evict方法刷新对应hashkey中的数据存储
/*
* Filename SimpleRedisCache.java
* Company 上海韵达快运总部。
* @author zhangFeng
* @version 1.0.0
*/
package com.leo.manage.system.cache;
import javax.annotation.Resource;
import org.apache.log4j.Logger;
import org.springframework.cache.Cache;
import org.springframework.cache.support.SimpleValueWrapper;
import org.springframework.data.redis.core.RedisTemplate;
import com.leo.util.Constants;
/**
* 注解缓存REDIS简单实现。<br>
* K-V方式缓存
*
* @author leo
* @since 1.0.0_2017年1月20日
*/
public class SysConfigSimpleRedisCache implements Cache {
Logger logger = Logger.getLogger(getClass());
@Resource(name="sysConfigRedisTemplate")
private RedisTemplate<Object, Object> sysConfigRedisTemplate;
private String name;
private int expire = -1;
private static final String CACHE_KEY = Constants.SYSCONFIG_CACHE_IN_REDIS;
public SysConfigSimpleRedisCache() {}
public SysConfigSimpleRedisCache(String name, int expire) {
super();
this.name = name;
this.expire = expire;
}
public SysConfigSimpleRedisCache(String name) {
super();
this.name = name;
}
@Override
public String getName() {
return this.name;
}
@Override
public Object getNativeCache() {
return null;
}
@Override
public ValueWrapper get(final Object key) {
long s = System.currentTimeMillis();
Object object = null;
if (key == null) {
return null;
}
if(logger.isDebugEnabled()){
logger.debug("get key: " + key);
}
try {
object = sysConfigRedisTemplate.opsForHash().get(CACHE_KEY, key);
} catch (Exception e) {
// 此处异常无抛出的途径
logger.warn("[SysConfigSimpleRedisCache.get ValueWrapper]操作异常", e);
}
if (logger.isInfoEnabled()) {
logger.info(key + ">redis-get ValueWrapper 处理时间" + (System.currentTimeMillis() - s));
}
return object == null ? null : new SimpleValueWrapper(object);
}
@Override
public void put(final Object key, final Object value) {
try {
if (value == null) {
return;
}
if (expire > 0) {
logger.warn("SysConfigSimpleRedisCache.put未实现[expire]!");
} else {
sysConfigRedisTemplate.opsForHash().put(CACHE_KEY, key, value);
}
} catch (Exception e) {
// 此处异常无抛出的途径
logger.warn("[put]操作异常", e);
}
}
@Override
public void evict(final Object key) {
try {
if (key == null) {
return;
}
sysConfigRedisTemplate.opsForHash().delete(CACHE_KEY, key);
if(logger.isDebugEnabled()) {
logger.debug("SysConfigSimpleRedisCache evict successfully: " + key);
}
} catch (Exception e) {
// 此处异常无抛出的途径
logger.warn("[evict]操作异常", e);
}
}
@Override
public void clear() {
try {
sysConfigRedisTemplate.delete(getName());
if(logger.isDebugEnabled()) {
logger.debug("SysConfigSimpleRedisCache clear successfully");
}
} catch (Exception e) {
// 此处异常无抛出的途径
logger.warn("[clear]操作异常", e);
}
}
public void setName(String name) {
this.name = name;
}
public int getExpire() {
return expire;
}
public void setExpire(int expire) {
this.expire = expire;
}
@SuppressWarnings("unchecked")
@Override
public <T> T get(final Object key, Class<T> type) {
long s = System.currentTimeMillis();
if (key == null) {
return null;
}
Object object = null;
try {
object = sysConfigRedisTemplate.opsForHash().get(CACHE_KEY, key);
} catch (Exception e) {
// 此处异常无抛出的途径
logger.warn("[SysConfigSimpleRedisCache.get <T>]操作异常", e);
}
if (logger.isInfoEnabled()) {
logger.info(key + ">redis-get <T> 处理时间" + (System.currentTimeMillis() - s));
}
return object == null ? null : ((T) object);
}
}
对应方法上通过注解操作:
package com.leo.system.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.leo.member.manage.system.dao.MBMNG_system_configDao;
import com.leo.member.manage.system.service.MBMNG_system_configCacheService;
import com.leo.util.Constants;
/**
* 系统缓存配置
* @author leo
* @since 3.5.6_2017年1月22日
*/
@Service(value = "configCacheService")
public class configCacheServiceImpl implements
configCacheService {
@Autowired
private configDao dataDao;
/**
* Cacheable注解,先从redis获取数据,取不到在从数据库获取
* 数据库获取之后把值放入redis中,对应的hashkey中的key通过key参数设定
*
* 通过key获取系统配置
*/
@Cacheable(value = {Constants.SYSCONFIG_CACHE_IN_REDIS}, key = "'sysconfig@'.concat(#sysCodeTxt != null? #sysCodeTxt : '')")
@Override
public String getSysValTxt(String sysCodeTxt) throws Exception {
return dataDao.getSysValTxt(sysCodeTxt);
}
/**
* Cacheable注解,先从redis获取数据,取不到在从数据库获取
* 数据库获取之后把值放入redis中,对应的hashkey中的key通过key参数设定
*
* 通过key获取系统配置中json数据里面jsonkey的值
* sysCodeTxt 系统配置key
* jsonKey 系统配置key对应的json数据里面的jsonkey
*/
@Cacheable(value = {Constants.SYSCONFIG_CACHE_IN_REDIS},key = "'sysconfigjson@'.concat(#sysCodeTxt != null? #sysCodeTxt : '').concat('@').concat(#jsonKey != null? #jsonKey : '')")
@Override
public String getSysValTxtJsonkey(String sysCodeTxt, String jsonKey) throws Exception {
String sysValTxt = dataDao.getSysValTxt(sysCodeTxt);
JSONObject parseObject = JSON.parseObject(sysValTxt);
return parseObject.getString(jsonKey);
}
/**
* 修改数据
* 修改数据时,先执行代码体的操作,然后会根据hashkey(Constants.SYSCONFIG_CACHE_IN_REDIS)清除redis的值
* allEntries 表示清除所有实体
*/
@CacheEvict(value = { Constants.SYSCONFIG_CACHE_IN_REDIS }, allEntries = true)
@Override
public void updateData(configVO vo,
RuntimeOperator operateInf) {
// TODO
configPO po = vo.toPO();
Object[] keys = po.getKeys();
configPO po0 = dataDao.getSingle(keys);
if (po0 == null) {
throw new ServiceException(ErrorCode.ERROR_RECORD_NOT_EXISTS);
}
po.setUpdate_time(Timestamp.valueOf(operateInf.getOperate_tm()));
dataDao.update(po);
}
}