spring+ehCache+redis多级缓存自定义实现
2017-01-07 15:35
405 查看
本文参考了http://blog.csdn.net/liaoyulin0609/article/details/51787020兄台的代码,进行了修改。
首先说一下需求:
1、希望如同原版的ehCache一样可以针对每个cache进行单独设置属性进行管理
2、集成redis做二级缓存,减少对数据库的访问
以下直接贴代码,做了修改的地方我会作说明
ehcache.xml
这里分别对myCache和myCache2进行不一样的过期时间设置
applicationContext.xml
redis.properties
UserService.java
接口实现类中试用了myCache和myCache2并且两个cache的key相同。
接下来是测试类
最重要的pom.xml差点忘了
<artifactId>ehcache-core</artifactId>
<groupId>net.sf.ehcache</groupId>
<version>2.4.8</version>
</dependency><dependency><groupId>net.sf.ehcache</groupId><artifactId>ehcache-jgroupsreplication</artifactId><version>1.7</version></dependency><dependency><groupId>org.jgroups</groupId><artifactId>jgroups</artifactId><version>3.0.9.Final</version></dependency><dependency><groupId>cglib</groupId><artifactId>cglib-nodep</artifactId><version>2.2.2</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-ehcache</artifactId><version>1.0.0</version></dependency><!--
spring aop jar --><dependency><groupId>aopalliance</groupId><artifactId>aopalliance</artifactId><version>1.0</version></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjrt</artifactId><version>1.7.4</version></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.7.4</version></dependency><dependency><groupId>cglib</groupId><artifactId>cglib</artifactId><version>2.2</version></dependency><dependency><groupId>ch.ethz.ganymed</groupId><artifactId>ganymed-ssh2</artifactId><version>build210</version></dependency></dependencies><!--
<build> --><!-- <finalName>ehCacheDemo</finalName> --><!-- <plugins> --><!-- Run the JUnit unit tests in an isolated classloader --><!-- <plugin> --><!-- <groupId>org.apache.maven.plugins</groupId> --><!-- <artifactId>maven-surefire-plugin</artifactId> --><!--
<version>2.4.2</version> --><!-- <configuration> --><!-- <skipTests>true</skipTests> --><!-- </configuration> --><!-- </plugin> --><!-- <plugin> --><!-- <groupId>org.apache.maven.plugins</groupId> --><!-- <artifactId>maven-war-plugin</artifactId> --><!-- <version>2.3</version>
--><!-- <configuration> --><!-- <webXml>src/main/webapp/WEB-INF/web.xml</webXml> --><!-- </configuration> --><!-- </plugin> --><!-- generate java doc --><!-- <plugin> --><!-- <groupId>org.apache.maven.plugins</groupId> --><!-- <artifactId>maven-javadoc-plugin</artifactId>
--><!-- <version>2.9.1</version> --><!-- <configuration> --><!-- <javadocDirectory>target/javadoc</javadocDirectory> --><!-- <reportOutputDirectory>target/javadoc</reportOutputDirectory> --><!-- <charset>UTF-8</charset> --><!-- <encoding>UTF-8</encoding> --><!--
<docencoding>UTF-8</docencoding> --><!-- <show>private</show> --><!-- </configuration> --><!-- </plugin> --><!-- 部署至本机 --><!-- <plugin> --><!-- <groupId>org.codehaus.cargo</groupId> --><!-- <artifactId>cargo-maven2-plugin</artifactId> --><!-- <version>1.0</version>
--><!-- <configuration> --><!-- <container> --><!-- <containerId>tomcat6x</containerId> --><!-- <home>D:\WebServer\apache-tomcat-6.0.39</home> --><!-- </container> --><!-- <configuration> --><!-- <type>existing</type> --><!-- <home>D:\WebServer\apache-tomcat-6.0.39</home>
--><!-- </configuration> --><!-- </configuration> --><!-- </plugin> --><!-- </plugins> --><!-- </build> --><build><finalName>ROOT</finalName><resources><resource><directory>src/main/java</directory><!-- maven打包漏掉mapper文件 --><includes><include>**/*.xml</include></includes><filtering>true</filtering></resource><resource><directory>src/main/resources</directory><!--
maven打包漏掉properties文件 --><includes><include>**/*.properties</include><include>**/*.xml</include></includes><filtering>true</filtering></resource></resources><plugins><!-- 跳过单元测试 --><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><configuration><skip>true</skip></configuration></plugin><plugin><!--
-Djetty.port=8080 jetty:run --><groupId>org.mortbay.jetty</groupId><artifactId>jetty-maven-plugin</artifactId><version>8.1.16.v20140903</version><configuration><connectors><connector implementation="org.eclipse.jetty.server.nio.SelectChannelConnector"><port>80</port></connector></connectors><stopPort>9967</stopPort><stopKey>foo</stopKey><scanIntervalSeconds>10</scanIntervalSeconds><webApp><contextPath></contextPath></webApp></configuration></plugin><plugin><!--
tomcat7:run --><groupId>org.apache.tomcat.maven</groupId><artifactId>tomcat7-maven-plugin</artifactId><version>2.1</version><configuration><port>8083</port><tomcat-url>http://localhost:8083/manager/html</tomcat-url><username>tomcat</username><password>admin</password><path>/</path></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>1.7</source><target>1.7</target></configuration></plugin></plugins></build></project>
我这demo里面啥都有,pom比较乱,凑合看吧
ehcache的jar版本可能会导致异常,请查阅ehcache-core版本导致异常
tried to access method net.sf.ehcache.config.CacheConfiguration.<init>()V from cl
首先说一下需求:
1、希望如同原版的ehCache一样可以针对每个cache进行单独设置属性进行管理
2、集成redis做二级缓存,减少对数据库的访问
以下直接贴代码,做了修改的地方我会作说明
ehcache.xml
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ehcache.sf.net/ehcache.xsd" updateCheck="false" monitoring="autodetect"> <diskStore path="java.io.tmpdir" /> <defaultCache maxElementsInMemory="1000" eternal="false" timeToLiveSeconds="120" overflowToDisk="false" /> <cache name="myCache" maxElementsInMemory="100" eternal="false" timeToLiveSeconds="1000" overflowToDisk="false" diskPersistent="false"> </cache> <cache name="myCache2" maxElementsInMemory="100" eternal="false" timeToLiveSeconds="1000" overflowToDisk="false" diskPersistent="false"> </cache> </ehcache>
这里分别对myCache和myCache2进行不一样的过期时间设置
applicationContext.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:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:cache="http://www.springframework.org/schema/cache" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-4.1.xsd"> <!--引入配置属性文件 --> <context:property-placeholder location="classpath:database.properties,classpath:redis.properties" /> <!--自动扫描含有@Service将其注入为bean --> <context:component-scan base-package="com.hulk.service" /> <context:component-scan base-package="com.hulk.redis" /> <!-- redis数据源 --> <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig"> <property name="maxIdle" value="${redis.maxIdle}" /> <property name="maxTotal" value="${redis.maxActive}" /> <property name="maxWaitMillis" value="${redis.maxWait}" /> <property name="testOnBorrow" value="${redis.testOnBorrow}" /> </bean> <!-- Spring-redis连接池管理工厂 --> <bean id="jedisConnectionFactory" 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 template --> <bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate"> <property name="connectionFactory" ref="jedisConnectionFactory" /> </bean> <!-- 缓存配置 --> <!-- 启用缓存注解功能(请将其配置在Spring主配置文件中) /开关 --> <!-- <cache:annotation-driven cache-manager="ehCacheCacheManager" /> --> <!-- Spring自己的基于java.util.concurrent.ConcurrentHashMap实现的缓存管理器(该功能是从Spring3.1开始提供的) --> <!-- <bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager"> <property name="caches"> <set> <bean name="myCache" class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean"/> </set> </property> </bean> --> <!-- 若只想使用Spring自身提供的缓存器,则注释掉下面的两个关于Ehcache配置的bean,并启用上面的SimpleCacheManager即可 --> <!-- Spring提供的基于的Ehcache实现的缓存管理器 --> <bean id="cacheManagerFactory" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"> <property name="configLocation" value="classpath:ehcache.xml" /> <!--true:单例,一个cacheManager对象共享;false:多个对象独立 --> <property name="shared" value="true" /> <property name="cacheManagerName" value="cacheManagerFactory" /> </bean> <bean id="ehCacheCacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager"> <property name="cacheManager" ref="cacheManagerFactory" /> </bean> <!-- myCache 操作对象 --> <bean id="myCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean"> <!-- cacheName对应ehcache.xml中的cache name="myCache" --> <property name="cacheName" value="myCache" /> <property name="cacheManager" ref="cacheManagerFactory" /> </bean> <!-- myCache2 操作对象 --> <bean id="myCache2" class="org.springframework.cache.ehcache.EhCacheFactoryBean"> <!-- cacheName对应ehcache.xml中的cache name="myCache2" --> <property name="cacheName" value="myCache2" /> <property name="cacheManager" ref="cacheManagerFactory" /> </bean> <!-- <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager"> --> <!-- <property name="cacheManager" ref="cacheManagerFactory" /> --> <!-- </bean> --> <!-- 自定义ehcache+redis --> <bean id="ehRedisCacheManager" class="org.springframework.cache.support.SimpleCacheManager"> <property name="caches"> <set> <bean id="ehRedisCache" class="com.hulk.ehcache.EhRedisCache"> <property name="redisTemplate" ref="redisTemplate" /> <property name="ehCache" ref="myCache" /> <property name="name" value="myCache" /> <!-- <property name="liveTime" value="3600"/> --> </bean> <bean id="ehRedisCache2" class="com.hulk.ehcache.EhRedisCache"> <property name="redisTemplate" ref="redisTemplate" /> <property name="ehCache" ref="myCache2" /> <property name="name" value="myCache2" /> <!-- <property name="liveTime" value="3600"/> --> </bean> </set> </property> </bean> <!-- 注解声明 --> <cache:annotation-driven cache-manager="ehRedisCacheManager" proxy-target-class="true" /> </beans>这里配置了两个“操作对象”对应ehRedisCacheManager中需要定义的实现bean 。这里可以把ehCache.xml中不同的cache配置到这里,并且class可以配置到同一个实现类当中。
redis.properties
# Redis settings redis.host=192.168.1.82 redis.port=6379 redis.pass= redis.timeout=20000 redis.maxIdle=200 redis.maxActive=500 redis.maxWait=20000 redis.testOnBorrow=trueEhRedisCache.java
package com.hulk.ehcache; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import net.sf.ehcache.Element; import org.slf4j.Logger; import org.slf4j.LoggerFactory; 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; //import com.hulk.service.EhCacheService; /** * 两级缓存,一级:ehcache,二级为redisCache * * @author yulin * */ public class EhRedisCache implements Cache { private static final Logger LOG = LoggerFactory .getLogger(EhRedisCache.class); private String name; /*** 一定容量的LRU队列 */ private net.sf.ehcache.Cache ehCache; /*** 无容量限制key带时效性 */ private RedisTemplate<String, Object> redisTemplate; private long liveTime = 1; // 默认1h=1*60*60 private int activeCount = 10; // @Autowired // private EhCacheService ehCacheService; @Override public String getName() { return this.name; } @Override public Object getNativeCache() { return this; } /** * 获取自定义缓存 */ @Override public ValueWrapper get(Object key) { Element value = ehCache.get(key); LOG.info("Cache L1 (ehcache) :{"+name+"}{"+key+"}={"+value+"}"); if (value != null) { // TODO 访问10次EhCache 强制访问一次redis 使得数据不失效 // if (value.getHitCount() < activeCount) { return (value != null ? new SimpleValueWrapper(value.getObjectValue()) : null); // } else { // value.resetAcce 13ac0 ssStatistics(); // } } final String keyStr = name+"_"+key.toString(); Object objectValue = redisTemplate.execute(new RedisCallback<Object>() { public Object doInRedis(RedisConnection connection) throws DataAccessException { byte[] key = keyStr.getBytes(); byte[] value = connection.get(key); if (value == null) { return null; } // 每次获得延迟时间 if (liveTime > 0) { connection.expire(key, liveTime); } return toObject(value); } }, true); ehCache.put(new Element(key, objectValue));// 取出来之后缓存到本地 LOG.info("Cache L2 (redis) :{"+name+"}{"+key+"}={"+objectValue+"}"); return (objectValue != null ? new SimpleValueWrapper(objectValue) : null); } /** * 更新自定义缓存 */ @Override public void put(Object key, Object value) { ehCache.put(new Element(key, value)); final String keyStr = key.toString(); final Object valueStr = value; redisTemplate.execute(new RedisCallback<Long>() { public Long doInRedis(RedisConnection connection) throws DataAccessException { byte[] keyb = keyStr.getBytes(); byte[] valueb = toByteArray(valueStr); connection.set(keyb, valueb); if (liveTime > 0) { connection.expire(keyb, liveTime); } return 1L; } }, true); } /** * 删除指定key缓存 */ @Override public void evict(Object key) { ehCache.remove(key); final String keyStr = key.toString(); redisTemplate.execute(new RedisCallback<Long>() { public Long doInRedis(RedisConnection connection) throws DataAccessException { return connection.del(keyStr.getBytes()); } }, true); } /** * 清除缓存 */ @Override public void clear() { ehCache.removeAll(); redisTemplate.execute(new RedisCallback<String>() { public String doInRedis(RedisConnection connection) throws DataAccessException { connection.flushDb(); return "clear done."; } }, true); } public net.sf.ehcache.Cache getEhCache() { return ehCache; } public void setEhCache(net.sf.ehcache.Cache ehCache) { this.ehCache = ehCache; } public RedisTemplate<String, Object> getRedisTemplate() { return redisTemplate; } public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) { this.redisTemplate = redisTemplate; } public long getLiveTime() { return liveTime; } public void setLiveTime(long liveTime) { this.liveTime = liveTime; } public void setName(String name) { this.name = name; } public int getActiveCount() { return activeCount; } public void setActiveCount(int activeCount) { this.activeCount = activeCount; } private byte[] toByteArray(Object obj) { byte[] bytes = null; ByteArrayOutputStream bos = new ByteArrayOutputStream(); try { ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(obj); oos.flush(); bytes = bos.toByteArray(); oos.close(); bos.close(); } catch (IOException ex) { ex.printStackTrace(); } return bytes; } private Object toObject(byte[] bytes) { Object obj = null; try { ByteArrayInputStream bis = new ByteArrayInputStream(bytes); ObjectInputStream ois = new ObjectInputStream(bis); obj = ois.readObject(); ois.close(); bis.close(); } catch (IOException ex) { ex.printStackTrace(); } catch (ClassNotFoundException ex) { ex.printStackTrace(); } return obj; } /* * (non-Javadoc) * * @see org.springframework.cache.Cache#get(java.lang.Object, * java.lang.Class) */ @Override public <T> T get(Object key, Class<T> type) { if (StringUtils.isEmpty(key) || null == type) { return null; } else { // final String finalKey; final Class<T> finalType = type; // if (key instanceof String) { // finalKey = (String) key; // } else { // finalKey = key.toString(); // } // final Object object = this.get(finalKey); final Object object = this.get(key); if (finalType != null && finalType.isInstance(object) && null != object) { return (T) object; } else { return null; } } } /* * (non-Javadoc) * * @see org.springframework.cache.Cache#putIfAbsent(java.lang.Object, * java.lang.Object) */ @Override public ValueWrapper putIfAbsent(Object key, Object value) { // final String finalKey; if (StringUtils.isEmpty(key) || StringUtils.isEmpty(value)) { return null; } else { // if (key instanceof String) { // finalKey = (String) key; // } else { // finalKey = key.toString(); // } // if (!StringUtils.isEmpty(finalKey)) { // final Object finalValue = value; this.put(key, value); // } } return new SimpleValueWrapper(value); } }我的key并没有使用原作者的自动生成策略,那么就存在可能存在多个cache重复的key,而存入redis的时候就会导致key重复,值覆盖或者值错乱的问题,所以在存入redis的时候把key加上了cache的name。或者redis的key拼接成“myCache:testKey”在redis中可以按照myCache进行归类
UserService.java
package com.hulk.service; import java.util.List; import java.util.Map; import com.alibaba.fastjson.JSONObject; import com.hulk.model.UserInfo; /** * 创建时间:2017-01-07 * * @author CUIJIAJUN * @version 1.0 */ public interface UserService { UserInfo getUserById(int id); String getUser(int id); String getUser2(int id); List<Map<String,Object>> getUsers(); int insertUserInfo(UserInfo userInfo) throws Exception; List<UserInfo> selectAll2(); /** * @param userId * @return */ void rmUserById(int userId); /** * */ void removeAll(); public Map getCache(); /** * 删除全部或者指定缓存名称 * @param cacheNames * @return */ JSONObject removeAllEhCache(String cacheNames); /** * 获取全部或指定缓存名称 * @param cacheNames * @return */ JSONObject getAllEhCache(String cacheNames); }UserServiceImpl.java
package com.hulk.service.impl; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import javax.annotation.Resource; import net.sf.ehcache.Cache; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.CachePut; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.alibaba.fastjson.JSONObject; import com.hulk.common.StringUtil; import com.hulk.dao.UserInfoMapper; import com.hulk.model.UserInfo; import com.hulk.service.EhCacheService; import com.hulk.service.UserService; /** * 创建时间:2017-01-07 * * @author CUIJIAJUN * @version 1.0 */ @Service("userService") public class UserServiceImpl implements UserService { @Resource private UserInfoMapper userInfoMapper; @Autowired private EhCacheService ehCacheService; // 将查询到的数据缓存到myCache中,并使用方法名称加上参数中的userNo作为缓存的key // 通常更新操作只需刷新缓存中的某个值,所以为了准确的清除特定的缓存,故定义了这个唯一的key,从而不会影响其它缓存值 @Cacheable(value = "myCache", key = "'get'+#id") public UserInfo getUserById(int id) { Cache cache = ehCacheService.getCache("myCache"); System.out.println("进来了查询方法......cache.getKeys()="+cache.getName()); UserInfo u = new UserInfo(); u.setUname("土豆大人"); return u; } // 将查询到的数据缓存到myCache中,并使用方法名称加上参数中的userNo作为缓存的key // 通常更新操作只需刷新缓存中的某个值,所以为了准确的清除特定的缓存,故定义了这个唯一的key,从而不会影响其它缓存值 @Cacheable(value = "myCache", key = "'getUser'") public String getUser(int id) { System.out.println("进来了查询方法......"); return "我是缓存嗷嗷嗷嗷嗷"; } @Cacheable(value = "myCache2", key = "'getUser'") public String getUser2(int id) { System.out.println("进来了查询方法......"); return "我是缓存嗷嗷嗷嗷嗷22222222222"; } @CacheEvict(value = "myCache", key = "'getUser'+#id") public void rmUserById(int id) { System.out.println("移除缓存中此用户号[" + id + "]的缓存"); } @Cacheable(value = "myCache", key = "") public List<Map<String, Object>> getUsers() { Cache cache = ehCacheService.getCache("myCache"); System.out.println("cache.getKeys()="+cache.getKeys()); return userInfoMapper.selectAll(); } // allEntries为true表示清除value中的全部缓存,默认为false @CacheEvict(value = "myCache", allEntries = true) public void removeAll() { System.out.println("移除全部myCache的缓存"); } //@CachePut更新缓存 @CachePut(value="myCache",key="'id:'+#p0['id']") public List<UserInfo> selectAll2() { return userInfoMapper.selectAll2(); } @Transactional(rollbackFor = Exception.class) public int insertUserInfo(UserInfo userInfo) throws Exception { int result = userInfoMapper.insertUserInfo(userInfo); if (true) { // throw new Exception("主动异常"); } System.out.println(result); return result; } @Cacheable(value="myCache",key="'getCache'") public Map getCache(){ Map map = new HashMap(); map.put("1", 1); return map; } @Override public JSONObject removeAllEhCache(String cacheNames) { if(StringUtil.isNotEmpty(cacheNames)){ String[] cacheNameStr = cacheNames.split(","); for(String cacheName : cacheNameStr){ ehCacheService.removeObjectByCacheName(cacheName); } }else{ ehCacheService.removeAll(); } JSONObject jsonObject = new JSONObject(); jsonObject.put("000","删除缓存成功"); return jsonObject; } @Override public JSONObject getAllEhCache(String cacheNames) { JSONObject jsonObject = new JSONObject(); jsonObject.put("000","获取缓存成功"); if(StringUtil.isNotEmpty(cacheNames)){ String[] cacheNameStr = cacheNames.split(","); for(String cacheName : cacheNameStr){ Map<Object, Object> map = ehCacheService.getObject(cacheName); jsonObject.put(cacheName+"("+map.size()+")",map); } }else{ List<Map<Object, Object>> list = ehCacheService.getAllObject(); for(Map<Object, Object> map : list){ for(Entry<Object, Object> entry:map.entrySet()){ Map value=(Map) entry.getValue(); jsonObject.put(entry.getKey().toString()+"("+value.size()+")",entry.getValue()); } } } return jsonObject; } }
接口实现类中试用了myCache和myCache2并且两个cache的key相同。
接下来是测试类
package com.hulk.service; import java.util.Date; import java.util.List; import java.util.Map; import org.apache.log4j.Logger; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.alibaba.fastjson.JSON; import com.hulk.model.UserInfo; import com.hulk.service.UserService; /** * 创建时间:2017-01-07 * * @author CUIJIAJUN * @version 1.0 */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath:applicationContext.xml","classpath:ehcache.xml"}) public class TestUserService { private static final Logger LOGGER = Logger .getLogger(TestUserService.class); @Autowired private UserService userService; @Test public void testGetUser() throws InterruptedException { long date1 = System.currentTimeMillis(); UserInfo userInfo = new UserInfo(); System.out.println("================================="); for(int i=0;i<1;i++){ // Thread.sleep(2000); System.out.println(i+"===="+userService.getUser(1)); System.out.println(i+"===="+userService.getUser(1)); System.out.println(i+"===="+userService.getUser2(1)); System.out.println(i+"===="+userService.getUser2(1)); } // Thread.sleep(5000); // userService.rmUserById(1); // for(int i=0;i<3;i++){ // System.out.println(i+"删除后查询===="+userService.getUser(1)); // } // userService.removeAll(); // for(int i=0;i<3;i++){ // System.out.println(i+"清理后查询===="+userService.getUser(1)); // } // System.out.println("================================="); // System.out.println("耗时===="+(System.currentTimeMillis()-date1)); } }
最重要的pom.xml差点忘了
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.hulk.sm</groupId> <artifactId>ehCache_redisDemo</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <name>ehCache_redisDemo Maven Webapp</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <spring.version>4.1.9.RELEASE</spring.version> <jackson.version>2.5.0</jackson.version> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <!-- spring --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> <scope>test</scope> </dependency> <!-- mybatis 包 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.2.8</version> </dependency> <!--mybatis spring 插件 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.2.2</version> </dependency> <!-- mysql连接 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.34</version> </dependency> <!-- 数据源 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.0.12</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.5</version> </dependency> <!-- slf4j --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.6</version> </dependency> <!-- servlet --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.0.1</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <!-- json --> <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-mapper-asl</artifactId> <version>1.9.13</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.4</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>${jackson.version}</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>${jackson.version}</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>${jackson.version}</version> </dependency> <!-- 文件上传 --> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.4</version> </dependency> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.1</version> </dependency> <!-- spring-redis实现 --> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>1.6.2.RELEASE</version> </dependency> <!-- redis客户端jar --> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.8.0</version> </dependency> <!-- Ehcache实现,用于参考 --> <dependency> <artifactId>ehcache</artifactId> <groupId>net.sf.ehcache</groupId> <version>2.7.2</version> </dependency>
<!-- 防止ehcache-core不匹配导致异常 --><dependency>
<artifactId>ehcache-core</artifactId>
<groupId>net.sf.ehcache</groupId>
<version>2.4.8</version>
</dependency><dependency><groupId>net.sf.ehcache</groupId><artifactId>ehcache-jgroupsreplication</artifactId><version>1.7</version></dependency><dependency><groupId>org.jgroups</groupId><artifactId>jgroups</artifactId><version>3.0.9.Final</version></dependency><dependency><groupId>cglib</groupId><artifactId>cglib-nodep</artifactId><version>2.2.2</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-ehcache</artifactId><version>1.0.0</version></dependency><!--
spring aop jar --><dependency><groupId>aopalliance</groupId><artifactId>aopalliance</artifactId><version>1.0</version></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjrt</artifactId><version>1.7.4</version></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.7.4</version></dependency><dependency><groupId>cglib</groupId><artifactId>cglib</artifactId><version>2.2</version></dependency><dependency><groupId>ch.ethz.ganymed</groupId><artifactId>ganymed-ssh2</artifactId><version>build210</version></dependency></dependencies><!--
<build> --><!-- <finalName>ehCacheDemo</finalName> --><!-- <plugins> --><!-- Run the JUnit unit tests in an isolated classloader --><!-- <plugin> --><!-- <groupId>org.apache.maven.plugins</groupId> --><!-- <artifactId>maven-surefire-plugin</artifactId> --><!--
<version>2.4.2</version> --><!-- <configuration> --><!-- <skipTests>true</skipTests> --><!-- </configuration> --><!-- </plugin> --><!-- <plugin> --><!-- <groupId>org.apache.maven.plugins</groupId> --><!-- <artifactId>maven-war-plugin</artifactId> --><!-- <version>2.3</version>
--><!-- <configuration> --><!-- <webXml>src/main/webapp/WEB-INF/web.xml</webXml> --><!-- </configuration> --><!-- </plugin> --><!-- generate java doc --><!-- <plugin> --><!-- <groupId>org.apache.maven.plugins</groupId> --><!-- <artifactId>maven-javadoc-plugin</artifactId>
--><!-- <version>2.9.1</version> --><!-- <configuration> --><!-- <javadocDirectory>target/javadoc</javadocDirectory> --><!-- <reportOutputDirectory>target/javadoc</reportOutputDirectory> --><!-- <charset>UTF-8</charset> --><!-- <encoding>UTF-8</encoding> --><!--
<docencoding>UTF-8</docencoding> --><!-- <show>private</show> --><!-- </configuration> --><!-- </plugin> --><!-- 部署至本机 --><!-- <plugin> --><!-- <groupId>org.codehaus.cargo</groupId> --><!-- <artifactId>cargo-maven2-plugin</artifactId> --><!-- <version>1.0</version>
--><!-- <configuration> --><!-- <container> --><!-- <containerId>tomcat6x</containerId> --><!-- <home>D:\WebServer\apache-tomcat-6.0.39</home> --><!-- </container> --><!-- <configuration> --><!-- <type>existing</type> --><!-- <home>D:\WebServer\apache-tomcat-6.0.39</home>
--><!-- </configuration> --><!-- </configuration> --><!-- </plugin> --><!-- </plugins> --><!-- </build> --><build><finalName>ROOT</finalName><resources><resource><directory>src/main/java</directory><!-- maven打包漏掉mapper文件 --><includes><include>**/*.xml</include></includes><filtering>true</filtering></resource><resource><directory>src/main/resources</directory><!--
maven打包漏掉properties文件 --><includes><include>**/*.properties</include><include>**/*.xml</include></includes><filtering>true</filtering></resource></resources><plugins><!-- 跳过单元测试 --><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><configuration><skip>true</skip></configuration></plugin><plugin><!--
-Djetty.port=8080 jetty:run --><groupId>org.mortbay.jetty</groupId><artifactId>jetty-maven-plugin</artifactId><version>8.1.16.v20140903</version><configuration><connectors><connector implementation="org.eclipse.jetty.server.nio.SelectChannelConnector"><port>80</port></connector></connectors><stopPort>9967</stopPort><stopKey>foo</stopKey><scanIntervalSeconds>10</scanIntervalSeconds><webApp><contextPath></contextPath></webApp></configuration></plugin><plugin><!--
tomcat7:run --><groupId>org.apache.tomcat.maven</groupId><artifactId>tomcat7-maven-plugin</artifactId><version>2.1</version><configuration><port>8083</port><tomcat-url>http://localhost:8083/manager/html</tomcat-url><username>tomcat</username><password>admin</password><path>/</path></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>1.7</source><target>1.7</target></configuration></plugin></plugins></build></project>
我这demo里面啥都有,pom比较乱,凑合看吧
ehcache的jar版本可能会导致异常,请查阅ehcache-core版本导致异常
tried to access method net.sf.ehcache.config.CacheConfiguration.<init>()V from cl
相关文章推荐
- 二十三、Spring Boot自定义Redis实现缓存机制
- Spring Cache+Redis实现自定义注解缓存
- 使用Spring Data +Redis实现缓存
- 深入理解Spring Redis的使用 (八)、Spring Redis实现 注解 自动缓存
- spring-data-redis 自定义缓存(@annotation+lua+aop)(一)
- 37. Spring Boot集成EHCache实现缓存机制【从零开始学Spring Boot】
- 分布式缓存技术redis学习系列(五)——redis实战(redis与spring整合,分布式锁实现)
- 用Spring和EHCache实现方法结果缓存所注意的问题
- spring + redis 实现数据的缓存
- Spring + ehcache 缓存配置,注解实现
- (35)Spring Boot集成Redis实现缓存机制【从零开始学Spring Boot】
- 35. Spring Boot集成Redis实现缓存机制【从零开始学Spring Boot】
- spring结合redis如何实现数据的缓存
- spring + ehcache + redis两级缓存实战篇(2)
- Mybatis自定义缓存——Redis实现
- spring+ehcache实现的缓存查询参数。
- Java开发框架spring实现自定义缓存标签
- 利用spring的拦截器自定义缓存的实现
- ehcache +mybatis+spring 自定义缓存策略
- spring+redis实现缓存