当前位置: 首页 > 编程日记 > 正文

(转)使用 Spring缓存抽象 支持 EhCache 和 Redis 混合部署

背景:最近项目组在开发本地缓存,其中用到了redis和ehcache,但是在使用注解过程中发现两者会出现冲突,这里给出解决两者冲突的具体方案。

spring-ehcache.xml配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cache="http://www.springframework.org/schema/cache"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-4.0.xsdhttp://www.springframework.org/schema/cachehttp://www.springframework.org/schema/cache/spring-cache-4.0.xsd"><description>ehcache缓存配置管理文件</description><bean id="ehCacheManagerFactory"class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"><property name="configLocation" value="classpath:ehcache/ehcache.xml" /></bean><bean id="ehCacheCacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager"><property name="cacheManager" ref="ehCacheManagerFactory" /></bean></beans>

整合Ehcache和Redis的cacheManager,并注入容器:

package org.szfs.basic.middle.cache;import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.ehcache.EhCacheCacheManager;
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;/*** 缓存集成配置类<p>* * 该类通过向spring提供统一的{@link CacheManager}以达到集成不同缓存中间件的目的,v0.1包括redis与ehcache<br>* 该类重写了{@link CachingConfigurerSupport#cacheManager()}和{@link CachingConfigurerSupport#keyGenerator()}的方法* * @author 51* @version $Id: SzfsCacheConfig.java, v 0.1 2018年2月5日 下午6:45:44 51 Exp $* * @see org.springframework.cache.annotation.CachingConfigurerSupport*/
@Configuration
@EnableCaching
public class SzfsCacheConfig extends CachingConfigurerSupport {/*** redis缓存前缀<p>* 用于通过缓存名前缀识别缓存中间件*/private static final String          REDIS_PREFIX = "redis-";@Autowired(required = false)private volatile RedisCacheManager   redisCacheManager;@Autowired(required = false)private volatile EhCacheCacheManager ehCacheCacheManager;public SzfsCacheConfig() {super();}/*** 构建CacheManager的实例szfsCacheManager<p>* * szfsCacheManager通过缓存名称<b>前缀</b>来识别缓存类型:* <ul>*   <li>"redis-": redis cache</li>*   <li> others : ehcache cache</li>* </ul>* 该实例是spring操作缓存所必须的,且需要保证唯一,这意味着,如果还需要Spring集成其它缓存中间件,仍然需要集成到szfsCacheManager<br>* * @see org.springframework.cache.annotation.CachingConfigurerSupport#cacheManager()*/@Bean("szfsCacheManager")@Overridepublic CacheManager cacheManager() {return new CacheManager() {@Overridepublic Collection<String> getCacheNames() {Collection<String> cacheNames = new ArrayList<String>();if (redisCacheManager != null) {cacheNames.addAll(redisCacheManager.getCacheNames());}if (ehCacheCacheManager != null) {cacheNames.addAll(ehCacheCacheManager.getCacheNames());}return cacheNames;}@Overridepublic Cache getCache(String name) {if (name.startsWith(REDIS_PREFIX)) {return redisCacheManager == null ? null : redisCacheManager.getCache(name);} else {return ehCacheCacheManager == null ? null : ehCacheCacheManager.getCache(name);}}};}/*** 构建默认的键生成器* @see org.springframework.cache.annotation.CachingConfigurerSupport#keyGenerator()*/@Bean@Overridepublic KeyGenerator keyGenerator() {return new KeyGenerator() {@Overridepublic Object generate(Object target, Method method, Object... params) {StringBuilder keyStrBuilder = new StringBuilder();keyStrBuilder.append(target.getClass().getName());keyStrBuilder.append(method.getName());for (Object _param : params) {keyStrBuilder.append(_param.toString());}return keyStrBuilder.toString();}};}public RedisCacheManager getRedisCacheManager() {return redisCacheManager;}public void setRedisCacheManager(RedisCacheManager redisCacheManager) {this.redisCacheManager = redisCacheManager;}public EhCacheCacheManager getEhCacheCacheManager() {return ehCacheCacheManager;}public void setEhCacheCacheManager(EhCacheCacheManager ehCacheCacheManager) {this.ehCacheCacheManager = ehCacheCacheManager;}}

redis相关配置:

<?xml version="1.0" encoding="UTF-8"?><!-- Spring集成redis sentinel配置,对应配置文件:redis-sentinel.properties --><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cache="http://www.springframework.org/schema/cache"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd"><description>Spring集成redis岗哨配置</description><!--配置 jedis pool --><bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"><property name="maxTotal" value="${redis.sentinel.jedis.pool.maxTotal}" /><property name="maxIdle" value="${redis.sentinel.jedis.pool.maxIdle}" /><property name="minIdle" value="${redis.sentinel.jedis.pool.minIdle}" /><property name="numTestsPerEvictionRun"value="${redis.sentinel.jedis.pool.numTestsPerEvictionRun}" /><property name="timeBetweenEvictionRunsMillis"value="${redis.sentinel.jedis.pool.timeBetweenEvictionRunsMillis}" /><property name="minEvictableIdleTimeMillis"value="${redis.sentinel.jedis.pool.minEvictableIdleTimeMillis}" /><property name="softMinEvictableIdleTimeMillis"value="${redis.sentinel.jedis.pool.softMinEvictableIdleTimeMillis}" /><property name="maxWaitMillis" value="${redis.sentinel.jedis.pool.maxWaitMillis}" /><property name="testOnBorrow" value="${redis.sentinel.jedis.pool.testOnBorrow}" /><property name="testWhileIdle" value="${redis.sentinel.jedis.pool.testWhileIdle}" /><property name="blockWhenExhausted"value="${redis.sentinel.jedis.pool.blockWhenExhausted}" /></bean><!-- 配置redisSentinelConfiguration --><bean id="redisSentinelConfiguration"class="org.springframework.data.redis.connection.RedisSentinelConfiguration"><property name="master"><bean class="org.springframework.data.redis.connection.RedisNode"><property name="name" value="mymaster" /></bean></property><property name="sentinels"><set><bean class="org.springframework.data.redis.connection.RedisNode"><constructor-arg name="host"value="${redis.sentinel.node1.host}" /><constructor-arg name="port"value="${redis.sentinel.node1.port}" /></bean><bean class="org.springframework.data.redis.connection.RedisNode"><constructor-arg name="host"value="${redis.sentinel.node2.host}" /><constructor-arg name="port"value="${redis.sentinel.node2.port}" /></bean><bean class="org.springframework.data.redis.connection.RedisNode"><constructor-arg name="host"value="${redis.sentinel.node3.host}" /><constructor-arg name="port"value="${redis.sentinel.node3.port}" /></bean></set></property></bean><!-- 配置JedisConnectionFactory --><bean id="jedisConnectionFactory"class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"><property name="password" value="${redis.sentinel.password}" /><constructor-arg ref="jedisPoolConfig" /><constructor-arg ref="redisSentinelConfiguration" /></bean><!-- 配置redisTemplate --><bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"><property name="connectionFactory" ref="jedisConnectionFactory" /><!-- 支持事务 --><property name="enableTransactionSupport" value="true" /><property name="keySerializer"><beanclass="org.springframework.data.redis.serializer.StringRedisSerializer" /></property><property name="valueSerializer"><beanclass="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer" /></property></bean><!-- 配置redisCacheManager --><bean id="redisCacheManager" class="org.springframework.data.redis.cache.RedisCacheManager"><constructor-arg name="redisOperations" ref="redisTemplate" /><!-- 默认有效期,单位:秒 --><property name="defaultExpiration" value="3600" /><!-- 多个缓存有效期,单位:秒 --><property name="expires"><map><entry key="redis-users" value="10" /></map></property></bean><!-- 配置RedisLockRegistry --><bean id="redisLockRegistry"class="org.springframework.integration.redis.util.RedisLockRegistry"><constructor-argtype="org.springframework.data.redis.connection.RedisConnectionFactory"ref="jedisConnectionFactory" /><constructor-arg type="java.lang.String" value="${redis.sentinel.registry.key}" /></bean></beans>

参考链接:http://blog.csdn.net/pmlpml/article/details/53116377

转载于:https://www.cnblogs.com/lixuwu/p/8427029.html

相关文章:

终端SVN常用命令

svn help 帮助 svn checkout path 从服务器checkout文件到本地(path是服务器上的目录&#xff0c;简写svn co path) svn add file_name 往代码库添加新的文件 svn commit -m "xxx" 提交添加的文件&#xff0c;或者本地做的修改到服务器端(“xxx”内为提交说明…

程序员怎么赚更多的钱_自由职业技巧:如何感到更加自信和赚更多钱

程序员怎么赚更多的钱Over my 10 years as a freelance developer, many fellow freelancers have asked me for advice. How can they make freelancing work for them?在我作为自由开发者的10年中&#xff0c;许多自由职业者都向我寻求建议。 他们如何让他们从事自由职业&am…

RedHat 7.0及CentOS 7.0禁止Ping的三种方法

作者&#xff1a;荒原之梦原文链接&#xff1a;http://zhaokaifeng.com/?p538前言&#xff1a; “Ping”属于ICMP协议&#xff08;即“Internet控制报文协议”&#xff09;&#xff0c;而ICMP协议是TCP/IP协议的一个子协议&#xff0c;工作在网际层。ICMP协议主要用于传输网络…

关于sql 增删改

1.更改数据库的名称 --更改数据库的名称&#xff0c;逗号前面是之前的&#xff0c;后面是改成的名 sp_renamedb student,xuesheng 2.表中有数据的情况下再添加列、删除列 --后来添加列&#xff0c;只能默认可以为空值 altear table shuiguo add [int] varchar(10) --int加上中括…

使用version遇到的那些坑

公司代码管理使用的SVN, 所以就用到了SVN工具version 公司没给买正版的version, 遇到各种崩溃, 各种坑 1. 更新项目时遇到网络不稳定的情况, 更新失败, 项目中的某个文件就莫名其妙的被锁定了 !!! 如果只是更新一个文件还好说, unlock一下就好了,但是如果你是一个文件夹全部…

docker手册_Docker手册

docker手册The concept of containerization itself is pretty old, but the emergence of the Docker Engine in 2013 has made it much easier to containerize your applications. 容器化本身的概念还很老&#xff0c;但是Docker Engine在2013年的出现使容器化应用程序变得更…

MongoDB修改器的使用1

为什么要使用修改器&#xff1f; 通常我们只会修改文档的一部分&#xff0c;这时候更新整个文档就显得很麻烦&#xff0c;通常是通过原子性的更新修改器来完成。 1."$set"修改器 "$set"用来指定某个字段&#xff0c;如果不存在&#xff0c;则创建。这对部…

4GL之Non-SCROLLING CURSOR

在4gl中CURSOR可以说是每一个程序中都会有的&#xff0c;而CURSOR又分为三种SCROLLING CURSOR、Non-SCROLLING CURSOR、LOCKING CURSOR。 Non-SCROLLING CURSOR的聲明有兩種&#xff0c;一種是先定義好sql語句到一個變量里&#xff1a; DECLARE cursor名 CURSOR FROM 變量…

项目总结三--波纹视图

波纹视图的使用 代码在github&#xff1a;https://github.com/wyon0313/YGMoireAnimation

vlookup示例_VLOOKUP示例–如何在Excel中执行VLOOKUP

vlookup示例Microsoft Excel includes a variety of different functions that help users with calculations of any kind. The functionality of Excel is so comprehensive that average users dont even take advantage of most utilities.Microsoft Excel包括各种不同的功…

MySQL--从库启动复制报错1236

链接:http://blog.csdn.net/yumushui/article/details/42742461 今天在搭建一个MySQL master-slave集群时&#xff0c;执行了change master命令&#xff0c;然后又 start slave 启动slave服务&#xff0c;结果查看salve状态就出现错误了&#xff1a; mysql> show slave stat…

使用Script元素发送JSONP请求

// 根据指定URL发送一个JSONP请求 //然后把解析得到的相应数据传递给回调函数 //在URL中添加一个名为jsonp的查询参数,用于指定该请求的回调函数的名称 function getJSONP(url, callback){//为本次请求创建一个唯一的回调函数名称var cbnum "cb"getJSONP.counter;va…

iOS 崩溃记录

dyld: Library not loaded: /System/Library/Frameworks/UserNotifications.framework/UserNotifications Referenced from: /var/containers/Bundle/Application/AEECAAFB-F14A-43AA-9FB8-8388CAC40122/DouLiao.app/DouLiao Reason: image not found 原因应该是iOS系统版本太…

以太坊Geth几种同步模式

链客&#xff0c;专为开发者而生&#xff0c;有问必答&#xff01; 此文章来自链客区块链技术问答社区&#xff0c;未经允许拒绝转载。 以太坊Geth几种同步模式 同步模式分类 –fast Enable fast syncing through state downloads –light Enable light client mode –s…

[转]Membership 到 .NET4.5 之 ASP.NET Identity

本文转自&#xff1a;http://www.cnblogs.com/jesse2013/p/membership-part3.html 我们前面已经讨论过了如何在一个网站中集成最基本的Membership功能&#xff0c;然后深入学习了Membership的架构设计。正所谓从实践从来&#xff0c;到实践从去&#xff0c;在我们把Membership的…

js填充select下拉框并选择默认值

/* 使用json数组填充下拉框并复选 *//* 初始化下拉框数据 */ var jsonStr { "data": [] }; for (var str in JsonStr.data) {jsonStr.data.push({ "value": JsonStr.data[str].value, "text": JsonStr.data[str].text }); }/* 调用BandSelectOb…

关于curl使用记录

因经常需要排除线上用户问题&#xff0c;查看用户数据请求结果&#xff0c;使用到curl命令&#xff0c;但是总是忘记&#xff0c;在此做下记录。 curl post请求命令行如下&#xff1a; curl -d "param0value0&param1value1" "url"

智能合约部署及调用

链客&#xff0c;专为开发者而生&#xff0c;有问必答&#xff01; 此文章来自链客区块链技术问答社区&#xff0c;未经允许拒绝转载。 智能合约部署及调用 以太坊区块链技术2.0版本对于行业应用的开发最主要特性就是实现了智能合约&#xff0c;本质上讲智能合约是由事件驱…

POP到指定的界面

int index (int)[[self.navigationController viewControllers]indexOfObject:self]; [self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:(index -2)] animated:YES];

js markdown chart flow

http://knsv.github.io/mermaid/#example-of-a-marked-renderer转载于:https://www.cnblogs.com/studyNT/p/5584399.html

使用Remix编译和部署以太坊智能合约

链客&#xff0c;专为开发者而生&#xff0c;有问必答&#xff01; 此文章来自链客区块链技术问答社区&#xff0c;未经允许拒绝转载。 使用Remix编译和部署以太坊智能合约 Remix 是一个开源的 Solidity 智能合约开发环境&#xff0c;提供基本的编译、部署至本地或测试网络…

Java之Array(数组)说明

代码说明&#xff1a; 1 package array;2 3 import java.util.ArrayList;4 import java.util.Arrays;5 import java.util.List;6 7 /**8 * Array使用说明&#xff1a;9 * 内容&#xff1a; 10 * 1、Array实例化&#xff1b; 11 * 2、Array与ArrayList转换&#xff1b; 12 …

创建操作/删除多行数据的UITableView的细节

首先注意需要重写-&#xff08;UITableViewCellEditingStyle&#xff09;tableView:&#xff08;UITableView *&#xff09;tableView editingStyleForRowAtIndexPath:&#xff08;NSIndexPath *&#xff09;indexPath 这里需要注意的是返回的结果应该是 return UITableViewCel…

每天进步一点点——Linux

http://blog.csdn.net/cywosp/article/category/443566/1转载于:https://www.cnblogs.com/zengkefu/p/5586780.html

用Go 构建一个区块链 -- Part 5: 地址

链客&#xff0c;专为开发者而生&#xff0c;有问必答&#xff01; 此文章来自链客区块链技术问答社区&#xff0c;未经允许拒绝转载。 比特币地址 这就是一个真实的比特币地址&#xff1a;1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa。这是史上第一个比特币地址&#xff0c;据说属于…

iOS 9 适配系列教程

转自&#xff1a;http://www.cocoachina.com/ios/20150703/12392.html 本文是投稿文章&#xff0c;作者&#xff1a;ChenYilong&#xff08;https://github.com/ChenYilong/iOS9AdaptationTips&#xff09; Demo1_iOS9网络适配_改用更安全的HTTPS iOS9把所有的http请求都改为ht…

AutoMocker单元测试

/// <summary>/// 测试获取所有物流/// </summary>[TestMethod]public void TestExpressController(){var Expresss new List<Express> { new Express{Code"01",Name"测试物流"}}.AsQueryable();var mocker new AutoMocker();mocker.U…

CSS.text不被选中

1、 text{-moz-user-select: none; /*火狐*/-webkit-user-select: none; /*webkit浏览器*/-ms-user-select: none; /*IE10*/-khtml-user-select: none; /*早期浏览器*/-o-user-select: none; /* Opera*/user-select: none;} 2、user-select - CSS3参考手册.html&#xff08;htt…

一个Solidity源文件的布局

链客&#xff0c;专为开发者而生&#xff0c;有问必答&#xff01; 此文章来自链客区块链技术问答社区&#xff0c;未经允许拒绝转载。 源文件可以包含任意数量的合约定义&#xff0c;include指令和pragma伪指令。 Pragma 版本 源文件可以&#xff08;并且应该&#xff09;使…

iOS 数字滚动 类似于老 - 虎- 机的效果

效果图 具体实现代码如下 ZCWScrollNumView.h文件 #import <UIKit/UIKit.h>typedef enum {ZCWScrollNumAnimationTypeNone,ZCWScrollNumAnimationTypeNormal,ZCWScrollNumAnimationTypeFromLast,ZCWScrollNumAnimationTypeRand,ZCWScrollNumAnimationTypeFast } ZCWScro…