博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【Spring】17、spring cache 与redis缓存整合
阅读量:4319 次
发布时间:2019-06-06

本文共 19853 字,大约阅读时间需要 66 分钟。

 cache,基本能够满足一般应用对缓存的需求,但现实总是很复杂,当你的用户量上去或者性能跟不上,总需要进行扩展,这个时候你或许对其提供的内存缓存不满意了,因为其不支持高可用性,也不具备持久化数据能力,这个时候,你就需要自定义你的缓存方案了,还好,spring 也想到了这一点。

本篇文章采用spring cache与进行整合,实现自己想要的缓存。

我们先配置redis:

第一步,要安装redis,这个自行百度,我们主要是配置redis。

增加一个redis配置文件,可以放在跟目录下

redis.host=192.168.0.43redis.port=6379redis.pass=2015redis.maxIdle=50redis.maxActive=50redis.maxWait=50redis.testOnBorrow=trueredis.timeout=1000

还需要在spring的配置文件中去配置redis

好了,配置redis完成了。

现在我们来配置spring的cache:

其实上面的配置文件,已经把redis与spring注解缓存的关系配置到了spring的xml文件中了。

 

对应的SystemRedisCache类是一个实现cache接口的自定义的缓存实现类。

import org.springframework.cache.Cache;import org.springframework.cache.support.SimpleValueWrapper;import org.springframework.dao.DataAccessException;import org.springframework.data.redis.connection.RedisConnection;import org.springframework.data.redis.core.RedisCallback;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.util.StringUtils;/** * 〈一句话功能简述〉
* 〈功能详细描述〉 * * @author Administrator * @see [相关类/方法](可选) * @since [产品/模块版本] (可选) */public class SystemRedisCache implements Cache { /** * Redis */ private RedisTemplate
redisTemplate; /** * 缓存名称 */ private String name; /** * 超时时间 */ private long timeout; /* * (non-Javadoc) * @see org.springframework.cache.Cache#getName() */ @Override public String getName() { return this.name; } /* * (non-Javadoc) * @see org.springframework.cache.Cache#getNativeCache() */ @Override public Object getNativeCache() { // TODO Auto-generated method stub return this.redisTemplate; } /* * (non-Javadoc) * @see org.springframework.cache.Cache#get(java.lang.Object) */ @Override public ValueWrapper get(Object key) { if (StringUtils.isEmpty(key)) { return null; } else { final String finalKey; if (key instanceof String) { finalKey = (String) key; } else { finalKey = key.toString(); } Object object = null; object = redisTemplate.execute(new RedisCallback
() { public Object doInRedis(RedisConnection connection) throws DataAccessException { byte[] key = finalKey.getBytes(); byte[] value = connection.get(key); if (value == null) { return null; } return SerializableObjectUtil.unserialize(value); } }); return (object != null ? new SimpleValueWrapper(object) : null); } } /* * (non-Javadoc) * @see org.springframework.cache.Cache#get(java.lang.Object, java.lang.Class) */ @SuppressWarnings("unchecked") @Override public
T get(Object key, Class
type) { if (StringUtils.isEmpty(key) || null == type) { return null; } else { final String finalKey; final Class
finalType = type; if (key instanceof String) { finalKey = (String) key; } else { finalKey = key.toString(); } final Object object = redisTemplate.execute(new RedisCallback
() { public Object doInRedis(RedisConnection connection) throws DataAccessException { byte[] key = finalKey.getBytes(); byte[] value = connection.get(key); if (value == null) { return null; } return SerializableObjectUtil.unserialize(value); } }); if (finalType != null && finalType.isInstance(object) && null != object) { return (T) object; } else { return null; } } } /* * (non-Javadoc) * @see org.springframework.cache.Cache#put(java.lang.Object, java.lang.Object) */ @Override public void put(final Object key, final Object value) { if (StringUtils.isEmpty(key) || StringUtils.isEmpty(value)) { return; } else { final String finalKey; if (key instanceof String) { finalKey = (String) key; } else { finalKey = key.toString(); } if (!StringUtils.isEmpty(finalKey)) { final Object finalValue = value; redisTemplate.execute(new RedisCallback
() { @Override public Boolean doInRedis(RedisConnection connection) { connection.set(finalKey.getBytes(), SerializableObjectUtil.serialize(finalValue)); // 设置超时间 connection.expire(finalKey.getBytes(), timeout); return true; } }); } } } /* * 根据Key 删除缓存 */ @Override public void evict(Object key) { if (null != key) { final String finalKey; if (key instanceof String) { finalKey = (String) key; } else { finalKey = key.toString(); } if (!StringUtils.isEmpty(finalKey)) { redisTemplate.execute(new RedisCallback
() { public Long doInRedis(RedisConnection connection) throws DataAccessException { return connection.del(finalKey.getBytes()); } }); } } } /* * 清楚系统缓存 */ @Override public void clear() { // TODO Auto-generated method stub // redisTemplate.execute(new RedisCallback
() { // public String doInRedis(RedisConnection connection) throws DataAccessException { // connection.flushDb(); // return "ok"; // } // }); } public RedisTemplate
getRedisTemplate() { return redisTemplate; } public void setRedisTemplate(RedisTemplate
redisTemplate) { this.redisTemplate = redisTemplate; } public void setName(String name) { this.name = name; } public long getTimeout() { return timeout; } public void setTimeout(long timeout) { this.timeout = timeout; }}

主要的方法就是get和put方法,里面的逻辑都是根据我们自己的需求去实现的。

 

现在有个问题,我们发现,在spring配置自己的注解缓存的配置文件中配置了多个cache,那spring是怎么去找到对应的cacheManager呢?

 

我们直接以代码给大家呈现出来:

/** *  * 公共接口 *  * @author Administrator * @see [相关类/方法](可选) * @since [产品/模块版本] (可选) */@Service("commonService")public class CommonServiceImpl implements CommonService {    /**     * 日志记录器     */    private static final Logger LOGGER = LoggerFactory.getLogger(CommonServiceImpl.class);    @Autowired    private DalClient dalClient;    /*     * @Autowired RedisTemplate
redisTemplate; */ /** * 根据名称获取自增序列squence的当前值 * * @param SequenceName 自增序列名称 * @return 自增序列当前值 * @see [相关类/方法](可选) * @since [产品/模块版本](可选) */ @Override public String getSequenceByName(String SequenceName) { if (StringUtils.isEmpty(SequenceName)) { LOGGER.error("自增序列名称为空,无法返回正常的自增序列值"); return null; } else { Map
paramMap = new HashMap
(); paramMap.put("sequenceName", SequenceName); // 查询sequence当前值 Map
resultMap = dalClient.queryForMap("common.GET_SEQUENCE_BY_NAME", paramMap); if (null != resultMap && !resultMap.isEmpty()) { return String.valueOf(resultMap.get("sequenceValue")); } else { return null; } } } /** * 根据上一级的城市编码 查询 所有下属城市 列表 * * @param parentCityCode * @return * @see [相关类/方法](可选) * @since [产品/模块版本](可选) */ @Override @Cacheable(value = "commonService.queryCityListByParentCode", key = "new String('commonService.queryCityListByParentCode')+#parentCityCode.toString()", condition = "null != #parentCityCode") public List
queryCityListByParentCode(final Integer parentCityCode) { Map
paramMap = new HashMap
(); if (null != parentCityCode) { // 根据所选省份 \ 城市 查询所属城市列表 paramMap.put("parentCityCode", parentCityCode); final List
cityListResult = dalClient.queryForList("T_CITY.SELECT_BY_PARENTCODE", paramMap, CityBean.class); return cityListResult; } else { final List
provinceListResult = dalClient.queryForList("T_CITY.SELECT_ALL_FIRST_STEP_CITY", paramMap, CityBean.class); return provinceListResult; } } /** * 根据上一级的行业编码 查询 所有下属所有行业 * * @param parentCityCode * @return * @see [相关类/方法](可选) * @since [产品/模块版本](可选) */ @Override @Cacheable(value = "commonService.queryIndustryListByParentCode", key = "new String('commonService.queryIndustryListByParentCode')+#parentIndustryCode.toString", condition = "null != #parentIndustryCode") public List
queryIndustryListByParentCode(final Integer parentIndustryCode) { Map
paramMap = new HashMap
(); if (null != parentIndustryCode) { paramMap.put("parentIndustryCode", parentIndustryCode); final List
industryListResult = dalClient.queryForList("T_INDUSTRY.SELECT_BY_PARENTCODE", paramMap, IndustryBean.class); return industryListResult; } else { final List
industryListResult = dalClient.queryForList( "T_INDUSTRY.SELECT_ALL_FIRST_STEP_INDUSTRY", paramMap, IndustryBean.class); return industryListResult; } } /** * 根据行业编码查询 行业信息 * * @param industryCode * @return * @see [相关类/方法](可选) * @since [产品/模块版本](可选) */ @Override @Cacheable(value = "commonService.queryIndustryInfoById", key = "new String('commonService.queryIndustryInfoById')+#industryCode", condition = "(null != #industryCode) and (#industryCode.length() > 0)") public IndustryBean queryIndustryInfoById(final String industryCode) { if (StringUtils.isEmpty(industryCode)) { return null; } else { Map
paramMap = new HashMap
(); paramMap.put("industryCode", industryCode); final IndustryBean industryInfoResult = dalClient.queryForObject("T_INDUSTRY.SELECT_BY_ID", paramMap, IndustryBean.class); return industryInfoResult; } } /** * 递归删除 元素 因为可能存在重复的 * * @param list 列表 * @param item 要删除的元素 * @see [相关类/方法](可选) * @since [产品/模块版本](可选) */ private void deleteListElement(ArrayList
list, String item) { if (null != list && !list.isEmpty() && StringUtils.isNotBlank(item)) { if (list.contains(item)) { list.remove(item); if (list.contains(item)) { deleteListElement(list, item); } } } } /** * 根据行业id查询 行业名称 * * @param industryIds 行业Id可能有多个 以分号分隔 * @return 行业名称列表 * @see [相关类/方法](可选) * @since [产品/模块版本](可选) */ @Override @Cacheable(value = "commonService.queryIndustryNameByIds", key = "new String('commonService.queryIndustryNameByIds')+#industryIds", condition = "null != #industryIds and #industryIds.length() > 0") public List
queryIndustryNameByIds(final String industryIds) { if (StringUtils.isBlank(industryIds)) { return null; } else { String[] industryIdArr = industryIds.split(";"); if (null != industryIdArr && industryIdArr.length > 0) { ArrayList
paramList = new ArrayList
(); paramList.addAll(Arrays.asList(industryIdArr)); if (null != paramList && !paramList.isEmpty()) { Map
paramMap = new HashMap
(); paramMap.put("industryIdList", paramList); // 查询行业列表 List
queryResultList = dalClient.queryForList("T_INDUSTRY.SELECT_BY_ID_LIST", paramMap, IndustryBean.class); // 封装查询结果 List
industryNameList = new ArrayList
(); if (null != queryResultList && !queryResultList.isEmpty()) { // 遍历查询列表 将已经存在的编码去掉 剩下的 就是 根據编码查询不出行业的 直接将行业的名字返回 String tempId; for (IndustryBean industryInfo : queryResultList) { if (null != industryInfo) { if (null == industryInfo.getIndustryCode()) { continue; } else { tempId = industryInfo.getIndustryCode().toString(); if (paramList.contains(tempId)) { deleteListElement(paramList, tempId); } if (StringUtils.isNotBlank(industryInfo.getIndustryName())) { industryNameList.add(industryInfo.getIndustryName()); } } } } } // 将根据编码查询不出来 的 行业编码 直接返回 industryNameList.addAll(paramList); return industryNameList; } } return null; } } /** * 根据城市id查询 城市名称 * * @param industryIds 行业Id可能有多个 以分号分隔 * @return 行业名称列表 * @see [相关类/方法](可选) * @since [产品/模块版本](可选) */ @Override @Cacheable(value = "commonService.queryCityNameByIds", key = "new String('commonService.queryCityNameByIds')+#cityIds", condition = "null != #cityIds and #cityIds.length() > 0") public List
queryCityNameByIds(String cityIds) { if (StringUtils.isBlank(cityIds)) { return null; } else { String replacyedCityIds = cityIds.replace(";", ","); String[] industryIdArr = replacyedCityIds.split(","); if (null != industryIdArr && industryIdArr.length > 0) { ArrayList
paramList = new ArrayList
(); paramList.addAll(Arrays.asList(industryIdArr)); if (null != paramList && !paramList.isEmpty()) { Map
paramMap = new HashMap
(); paramMap.put("cityIdList", paramList); // 查询行业列表 List
queryResultList = dalClient.queryForList("T_CITY.SELECT_BY_ID_LIST", paramMap, CityBean.class); List
industryNameList = new ArrayList
(); if (null != queryResultList && !queryResultList.isEmpty()) { // 遍历查询列表 将已经存在的编码去掉 剩下的 就是 根據编码查询不出行业的 直接将行业的名字返回 // 封装查询结果 String tempId; for (CityBean industryInfo : queryResultList) { if (null != industryInfo) { if (null == industryInfo.getCityCode()) { continue; } else { tempId = industryInfo.getCityCode().toString(); if (paramList.contains(tempId)) { deleteListElement(paramList, tempId); } if (StringUtils.isNotBlank(industryInfo.getCityName())) { industryNameList.add(industryInfo.getCityName()); } } } } } // 将根据编码查询不出来 的 行业编码 直接返回 industryNameList.addAll(paramList); return industryNameList; } } return null; } } /** * 查询第一级所有职位 * * @return */ @Override public List
queryFirstJobList() { /* * List
redisIndustryListResult = redisTemplate.execute(new RedisCallback
>() { * @Override public List
doInRedis(RedisConnection connection) { byte[] industryListList = * connection.get((RedisConstants.JOB_FIRST_LIST).getBytes()); if (null != industryListList && * industryListList.length > 0) { return (List
) SerializableObjectUtil.unserialize(industryListList); * } else { return null; } } }); if (null != redisIndustryListResult && !redisIndustryListResult.isEmpty()) { * return redisIndustryListResult; } else { */ final List
queryIndustryListResult = dalClient.queryForList("T_JOB_TYPE.SELECT_FIRST_JOB_CODE", null, JobTypeVo.class); /* * if (null != queryIndustryListResult && !queryIndustryListResult.isEmpty()) { redisTemplate.execute(new * RedisCallback
() { * @Override public Boolean doInRedis(RedisConnection connection) { * connection.set((RedisConstants.JOB_FIRST_LIST).getBytes(), * SerializableObjectUtil.serialize(queryIndustryListResult)); return true; } }); } */ return queryIndustryListResult; /* } */ } /** * 查询 对应级别的职位信息 * * @param typeValue * @param jobCode * @return */ @Override public List
queryJobTypeList(final int typeValue, final int jobCode) { /* * List
redisIndustryListResult = redisTemplate.execute(new RedisCallback
>() { * @Override public List
doInRedis(RedisConnection connection) { byte[] industryListList = * connection.get((RedisConstants.JOB_FIRST_LIST + typeValue + jobCode) .getBytes()); if (null != * industryListList && industryListList.length > 0) { return (List
) * SerializableObjectUtil.unserialize(industryListList); } else { return null; } } }); if (null != * redisIndustryListResult && !redisIndustryListResult.isEmpty()) { return redisIndustryListResult; } else { */ Map
paramMap = new HashMap
(); paramMap.put("typeValue", typeValue); paramMap.put("jobFirstCode", jobCode); final List
queryResult = dalClient.queryForList("T_JOB_TYPE.SELECT_BY_JOB_CODE", paramMap, JobTypeBean.class); /* * if (null != queryResult && !queryResult.isEmpty()) { redisTemplate.execute(new RedisCallback
() { * @Override public Boolean doInRedis(RedisConnection connection) { * connection.set((RedisConstants.JOB_FIRST_LIST + typeValue + jobCode).getBytes(), * SerializableObjectUtil.serialize(queryResult)); return true; } }); } */ return queryResult; /* } */ } /** * 判断学校是否 特殊学校 * * @param schoolName 学校名称 * @param schoolType 学校分类(1:211 暂无其他) * @return true:是, false:否 * @see [相关类/方法](可选) * @since [产品/模块版本](可选) */ @Override @Cacheable(value = "commonService.isSpecialSchool", key = "new String('commonService.isSpecialSchool')+#schoolName + #schoolType", condition = "null != #schoolName and null !=#schoolType and #schoolName.length() > 0") public boolean isSpecialSchool(String schoolName, int schoolType) { if (StringUtils.isEmpty(schoolName)) { return false; } else { Map
paramMap = new HashMap
(); paramMap.put("schoolName", schoolName); paramMap.put("schoolType", schoolType); Map
resultMap = dalClient.queryForMap("T_MY_SPECIAL_SCHOOL.SELECT_BY_NAME_TYPE", paramMap); if (null != resultMap && !resultMap.isEmpty() && resultMap.containsKey("NUM")) { return (long) resultMap.get("NUM") > 0; } else { return false; } } } /** * 根据城市名称获取 城市所在 省份名称 * * @param cityNames * @return * @see [相关类/方法](可选) * @since [产品/模块版本](可选) */ @Override @Cacheable(value = "commonService.getProvinceByCity", key = "new String('commonService.getProvinceByCity')+#cityNames", condition = "null != #cityNames and #cityNames.length() > 0") public String getProvinceByCity(final String cityNames) { if (StringUtils.isBlank(cityNames)) { return null; } else { String[] cityArr = cityNames.split("、"); Map
paramMap = new HashMap
(); Map
resultMap; String provinceName; List
provinceLait = new ArrayList
(); for (String cityName : cityArr) { if (StringUtils.isNotBlank(cityName)) { paramMap.put("cityName", cityName); resultMap = dalClient.queryForMap("T_CITY.SELECT_PROVINCE_NAMEBY_CITY_NAME", paramMap); if (null != resultMap && !resultMap.isEmpty() && resultMap.containsKey("provinceName")) { provinceName = String.valueOf(resultMap.get("provinceName")); if (!provinceLait.contains(provinceName)) { provinceLait.add(provinceName); } } } } StringBuffer sb = new StringBuffer(100); if (!provinceLait.isEmpty()) { for (int i = 0; i < provinceLait.size(); i++) { if (i < provinceLait.size() - 1) { sb.append(provinceLait.get(i)).append(","); } else { sb.append(provinceLait.get(i)); } } } return sb.toString(); } }

已queryCityListByParentCode方法为例:

 

在这个方法上面有@Cacheable这个注解,这个是spring3.1以后增加的注解缓存标签,它会根据value = "commonService.queryCityListByParentCode"中value的属性值去查找我们配置在spring的xml文件中的name属性去查找,找到对应的配置文件后,该方法会通过我们自定义的缓存实现类去实现对应的逻辑,如果对spring注解的意义不清楚的可以先去了解下spring cache注解的含义。

友情链接:

转载于:https://www.cnblogs.com/wangzhongqiu/p/6958655.html

你可能感兴趣的文章
jxl写入excel实现数据导出功能
查看>>
linux文件目录类命令|--cp指令
查看>>
.net MVC 404错误解决方法
查看>>
linux系统目录结构
查看>>
git
查看>>
btn按钮之间事件相互调用
查看>>
Entity Framework 4.3.1 级联删除
查看>>
codevs 1163:访问艺术馆
查看>>
冲刺Noip2017模拟赛3 解题报告——五十岚芒果酱
查看>>
并查集
查看>>
sessionStorage
查看>>
代码示例_进程
查看>>
Java中关键词之this,super的使用
查看>>
学习进度
查看>>
“此人不存在”
查看>>
github.com加速节点
查看>>
解密zend-PHP凤凰源码程序
查看>>
python3 序列分片记录
查看>>
Atitit.git的存储结构and 追踪
查看>>
atitit 读书与获取知识资料的attilax的总结.docx
查看>>