- <!-- Redis客户端 -->
- <dependency>
- <groupId>redis.clients</groupId>
- <artifactId>jedis</artifactId>
- <version>2.8.0</version>
- </dependency>
- <!-- Jackson Json处理工具包 -->
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-databind</artifactId>
- <version>2.7.3</version>
- </dependency>
spring 配置文件添加
- <!-- 开启切面代理 使得spring认识 @Aspect -->
- <aop:aspectj-autoproxy/>
然后定义两个标注在Service实现方法上的注解,用于传递类型参数:
- import java.lang.annotation.Documented;
- import java.lang.annotation.ElementType;
- import java.lang.annotation.Retention;
- import java.lang.annotation.RetentionPolicy;
- import java.lang.annotation.Target;
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.METHOD)
- @Documented
- public @interface RedisCache {
- Class type();
- public int expire() default 0; //缓存多少秒,默认无限期
- }
- import java.lang.annotation.ElementType;
- import java.lang.annotation.Retention;
- import java.lang.annotation.RetentionPolicy;
- import java.lang.annotation.Target;
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.METHOD)
- public @interface RedisEvict {
- Class type();
- }
注解的使用方式如下:
- @RedisCache(type = User.class, expire = 200000000)
- public List<User> findUsersByGroupId(Integer group_id) {
- return groupDao.findUsersByGroupId(group_id);
- }
- @RedisEvict(type = User.class)// 表示该方法需要执行清除缓存逻辑
- public void updateUserByPhone(String nickName,String phone) {
- UserDao.updateUserByPhone(nickName, phone);
- }
JsonUtils
- import java.io.IOException;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import java.util.Map.Entry;
- import org.apache.log4j.Logger;
- import com.fasterxml.jackson.core.type.TypeReference;
- import com.fasterxml.jackson.databind.JavaType;
- import com.fasterxml.jackson.databind.ObjectMapper;
- public class JsonUtils {
- private static Logger logger = Logger.getLogger(JsonUtils.class);
- // 定义jackson对象
- private static final ObjectMapper MAPPER = new ObjectMapper();
- /**
- * 将对象转换成json字符串。
- *
- * @param data
- * @return
- * @throws IOException
- */
- public static String objectToJson(Object data) {
- try {
- String string = MAPPER.writeValueAsString(data);
- return string;
- } catch (Exception e) {
- e.printStackTrace();
- }
- return null;
- }
- /**
- * 将json结果集转化为对象
- *
- * @param jsonData
- * json数据
- * @param clazz
- * 对象中的object类型
- * @return
- */
- public static <T> T jsonToPojo(String jsonData, Class<T> beanType) {
- try {
- T t = MAPPER.readValue(jsonData, beanType);
- return t;
- } catch (Exception e) {
- e.printStackTrace();
- }
- return null;
- }
- /**
- * 将json数据转换成pojo对象list
- *
- * @param jsonData
- * @param beanType
- * @return
- */
- public static <T> List<T> jsonToList(String jsonData, Class<T> beanType) {
- JavaType javaType = MAPPER.getTypeFactory().constructParametricType(
- List.class, beanType);
- try {
- List<T> list = MAPPER.readValue(jsonData, javaType);
- return list;
- } catch (Exception e) {
- e.printStackTrace();
- }
- return null;
- }
- /**
- * json string convert to map with javaBean
- */
- public static <T> Map<String, T> jsonTomap(String jsonStr, Class<T> clazz)
- throws Exception {
- Map<String, Map<String, Object>> map = MAPPER.readValue(jsonStr,
- new TypeReference<Map<String, T>>() {
- });
- Map<String, T> result = new HashMap<String, T>();
- for (Entry<String, Map<String, Object>> entry : map.entrySet()) {
- result.put(entry.getKey(), mapTopojo(entry.getValue(), clazz));
- }
- return result;
- }
- /**
- * json string convert to map
- */
- public static <T> Map<String, Object> jsonTomap(String jsonStr) {
- try {
- return MAPPER.readValue(jsonStr, Map.class);
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- return null;
- }
- /**
- * map convert to javaBean
- */
- public static <T> T mapTopojo(Map map, Class<T> clazz) {
- try {
- return MAPPER.convertValue(map, clazz);
- } catch (Exception e) {
- e.printStackTrace();
- }
- return null;
- }
- }
- import java.util.List;
- import org.aspectj.lang.JoinPoint;
- import org.aspectj.lang.ProceedingJoinPoint;
- import org.aspectj.lang.annotation.Around;
- import org.aspectj.lang.annotation.Aspect;
- import org.aspectj.lang.annotation.Before;
- import org.aspectj.lang.reflect.MethodSignature;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Component;
- import com.core.annotation.RedisCache;
- import com.core.annotation.RedisEvict;
- import com.jedis.dao.JedisClient;
- import com.utils.JsonUtils;
- @Aspect
- @Component
- public class CacheInterceptor {
- @Autowired
- JedisClient jedisClient;
- //前置由于数据库数据变更 清理redis缓存
- @Before("@annotation(redisEvict)")
- public void <span style="font-family:Consolas, Courier New, Courier, mono, serif;"><span style="line-height: 18px; background-color: rgb(248, 248, 248);">doBefore</span></span>(JoinPoint jp,RedisEvict redisEvict){
- try{
- String modelName = redisEvict.type().getName();
- // 清除对应缓存
- jedisClient.del(modelName);
- }catch (Exception e) {
- e.printStackTrace();
- System.out.println("缓存服务器出现问题,发邮箱,发信息...");
- }
- }
- // 配置环绕方法
- @Around("@annotation(redisCache)")
- public Object doAround(ProceedingJoinPoint pjp, RedisCache redisCache)
- throws Throwable {
- // 得到被代理的方法
- // Method me = ((MethodSignature) pjp.getSignature()).getMethod();
- // Class modelType = me.getAnnotation(RedisCache.class).type();
- //得到注解上类型
- Class modelType = redisCache.type();
- //System.out.println(modelType.getName());
- // 去Redis中看看有没有我们的数据 包名+ 类名 + 方法名 + 参数(多个)
- String cacheKey = getCacheKey(pjp);
- System.out.println(cacheKey);
- String value = null;
- try {//当取redis发生异常时,为了不影响程序正常执行,需要try..catch()...
- //检查redis中是否有缓存
- value = jedisClient.hget(modelType.getName(),cacheKey);
- } catch (Exception e) {
- e.printStackTrace();
- System.out.println("缓存服务器出现问题,发邮箱,发信息...");
- }
- // result是方法的最终返回结果
- Object result = null;
- if (null == value) {
- // 缓存未命中
- System.out.println("缓存未命中");
- // 后端查询数据
- result = pjp.proceed();
- try {//当取redis发生异常时,为了不影响程序正常执行,需要try..catch()...
- // 序列化结果放入缓存
- String json = serialize(result);
- jedisClient.hset(modelType.getName(), cacheKey, json);
- if(redisCache.expire()>0) {
- jedisClient.expire(cacheKey, redisCache.expire());//设置缓存时间
- }
- } catch (Exception e) {
- e.printStackTrace();
- System.out.println("缓存服务器出现问题,发邮箱,发信息...");
- }
- } else {
- try{//当数据转换失败发生异常时,为了不影响程序正常执行,需要try..catch()...
- // int i =1/0;
- // 得到被代理方法的返回值类型
- Class returnType = ((MethodSignature) pjp.getSignature()).getReturnType();
- //把json反序列化
- result = deserialize(value, returnType, modelType);
- // 缓存命中
- System.out.println("缓存命中");
- } catch (Exception e) {
- //数据转换失败,到后端查询数据
- result = pjp.proceed();
- e.printStackTrace();
- System.out.println("缓存命中,但数据转换失败...");
- }
- }
- return result;
- }
- protected String serialize(Object target) {
- return JsonUtils.objectToJson(target);
- }
- protected Object deserialize(String jsonString, Class clazz, Class modelType) {
- // 序列化结果应该是List对象
- if (clazz.isAssignableFrom(List.class)) {
- return JsonUtils.jsonToList(jsonString, modelType);
- }
- // 序列化结果是普通对象
- return JsonUtils.jsonToPojo(jsonString, clazz);
- }
- // 包名+ 类名 + 方法名 + 参数(多个) 生成Key
- public String getCacheKey(ProceedingJoinPoint pjp) {
- StringBuffer key = new StringBuffer();
- // 包名+ 类名 cn.core.serice.product.ProductServiceImpl.productList
- String packageName = pjp.getTarget().getClass().getName();
- key.append(packageName);
- // 方法名
- String methodName = pjp.getSignature().getName();
- key.append(".").append(methodName);
- // 参数(多个)
- Object[] args = pjp.getArgs();
- for (Object arg : args) {
- // 参数
- key.append(".").append(arg.toString());
- }
- return key.toString();
- }
- }
- public interface JedisClient {
- String get(String key);
- byte[] get(byte[] key);
- String set(String key, String value);
- String set(byte[] key, byte[] value);
- String hget(String hkey, String key);
- long hset(String hkey, String key, String value);
- long incr(String key);
- long expire(String key, int second);
- long ttl(String key);
- long del(String key);
- long hdel(String hkey, String key);
- }
- JedisClientSingle
- import org.springframework.beans.factory.annotation.Autowired;
- import redis.clients.jedis.Jedis;
- import redis.clients.jedis.JedisPool;
- import com.edl.jedis.dao.JedisClient;
- public class JedisClientSingle implements JedisClient{
- @Autowired
- private JedisPool jedisPool;
- @Override
- public String get(String key) {
- Jedis jedis = jedisPool.getResource();
- String string = jedis.get(key);
- jedis.close();
- return string;
- }
- @Override
- public String set(String key, String value) {
- Jedis jedis = jedisPool.getResource();
- String string = jedis.set(key, value);
- jedis.close();
- return string;
- }
- @Override
- public String hget(String hkey, String key) {
- Jedis jedis = jedisPool.getResource();
- String string = jedis.hget(hkey, key);
- jedis.close();
- return string;
- }
- @Override
- public long hset(String hkey, String key, String value) {
- Jedis jedis = jedisPool.getResource();
- Long result = jedis.hset(hkey, key, value);
- jedis.close();
- return result;
- }
- @Override
- public long incr(String key) {
- Jedis jedis = jedisPool.getResource();
- Long result = jedis.incr(key);
- jedis.close();
- return result;
- }
- @Override
- public long expire(String key, int second) {
- Jedis jedis = jedisPool.getResource();
- Long result = jedis.expire(key, second);
- jedis.close();
- return result;
- }
- @Override
- public long ttl(String key) {
- Jedis jedis = jedisPool.getResource();
- Long result = jedis.ttl(key);
- jedis.close();
- return result;
- }
- @Override
- public long del(String key) {
- Jedis jedis = jedisPool.getResource();
- Long result = jedis.del(key);
- jedis.close();
- return result;
- }
- @Override
- public long hdel(String hkey, String key) {
- Jedis jedis = jedisPool.getResource();
- Long result = jedis.hdel(hkey, key);
- jedis.close();
- return result;
- }
- @Override
- public byte[] get(byte[] key) {
- Jedis jedis = jedisPool.getResource();
- byte[] result = jedis.get(key);
- jedis.close();
- return result;
- }
- @Override
- public String set(byte[] key, byte[] value) {
- Jedis jedis = jedisPool.getResource();
- String result = jedis.set(key, value);
- jedis.close();
- return result;
- }
- }
JedisClientCluster
- public class JedisClientCluster implements JedisClient {
- @Autowired
- private JedisCluster jedisCluster;
- @Override
- public String get(String key) {
- return jedisCluster.get(key);
- }
- @Override
- public String set(String key, String value) {
- return jedisCluster.set(key, value);
- }
- @Override
- public String hget(String hkey, String key) {
- return jedisCluster.hget(hkey, key);
- }
- @Override
- public long hset(String hkey, String key, String value) {
- return jedisCluster.hset(hkey, key, value);
- }
- @Override
- public long incr(String key) {
- return jedisCluster.incr(key);
- }
- @Override
- public long expire(String key, int second) {
- return jedisCluster.expire(key, second);
- }
- @Override
- public long ttl(String key) {
- return jedisCluster.ttl(key);
- }
- @Override
- public long del(String key) {
- return jedisCluster.del(key);
- }
- @Override
- public long hdel(String hkey, String key) {
- return jedisCluster.hdel(hkey, key);
- }
- @Override
- public byte[] get(byte[] key) {
- // TODO Auto-generated method stub
- return jedisCluster.get(key);
- }
- @Override
- public String set(byte[] key, byte[] value) {
- // TODO Auto-generated method stub
- return jedisCluster.set(key, value);
- }
- }
spring-jedis.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:context="http://www.springframework.org/schema/context"
- xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
- xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:task="http://www.springframework.org/schema/task"
- xsi:schemaLocation="http://www.springframework.org/schema/mvc
- http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
- http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
- http://www.springframework.org/schema/context
- http://www.springframework.org/schema/context/spring-context-3.0.xsd
- http://www.springframework.org/schema/aop
- http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
- http://www.springframework.org/schema/tx
- http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
- http://www.springframework.org/schema/task
- http://www.springframework.org/schema/task/spring-task-3.0.xsd">
- <context:component-scan base-package="com.core" />
- <!-- jedis客户端单机版 -->
- <bean id="redisClient" class="redis.clients.jedis.JedisPool">
- <constructor-arg name="host" value="192.168.1.87"></constructor-arg>
- <constructor-arg name="port" value="6379"></constructor-arg>
- </bean>
- <bean id="jedisClient" class="com.edl.jedis.dao.impl.JedisClientSingle" />
- <!-- jedis集群版配置 -->
- <!-- <bean id="redisClient" class="redis.clients.jedis.JedisCluster">
- <constructor-arg name="nodes">
- <set>
- <bean class="redis.clients.jedis.HostAndPort">
- <constructor-arg name="host" value="192.168.1.87"></constructor-arg>
- <constructor-arg name="port" value="7006"></constructor-arg>
- </bean>
- <bean class="redis.clients.jedis.HostAndPort">
- <constructor-arg name="host" value="192.168.1.87"></constructor-arg>
- <constructor-arg name="port" value="7001"></constructor-arg>
- </bean>
- <bean class="redis.clients.jedis.HostAndPort">
- <constructor-arg name="host" value="192.168.1.87"></constructor-arg>
- <constructor-arg name="port" value="7002"></constructor-arg>
- </bean>
- <bean class="redis.clients.jedis.HostAndPort">
- <constructor-arg name="host" value="192.168.1.87"></constructor-arg>
- <constructor-arg name="port" value="7003"></constructor-arg>
- </bean>
- <bean class="redis.clients.jedis.HostAndPort">
- <constructor-arg name="host" value="192.168.1.87"></constructor-arg>
- <constructor-arg name="port" value="7004"></constructor-arg>
- </bean>
- <bean class="redis.clients.jedis.HostAndPort">
- <constructor-arg name="host" value="192.168.1.87"></constructor-arg>
- <constructor-arg name="port" value="7005"></constructor-arg>
- </bean>
- </set>
- </constructor-arg>
- <constructor-arg name="poolConfig" ref="jedisPoolConfig"></constructor-arg>
- </bean>
- <bean id="jedisClientCluster" class="com.edl.jedis.dao.impl.JedisClientCluster"></bean> -->
- </beans>