您的位置:首页 > 数据库 > Redis

spring+ehCache+redis多级缓存自定义实现

2017-01-07 15:35 405 查看
本文参考了http://blog.csdn.net/liaoyulin0609/article/details/51787020兄台的代码,进行了修改。

首先说一下需求:

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=true
EhRedisCache.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


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息