博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
深入理解Spring Redis的使用 (六)、用Spring Aop 实现注解Dao层的自动Spring Redis缓存...
阅读量:6908 次
发布时间:2019-06-27

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

摘要: 主要针对Dao层的一些数据库查询的操作,数据实时性不强,直接加入缓存。当缓存中有的时候,就使用缓存中的数据。这样的方法,最终仅仅使用一个注解实现。对于之前的hibernate二级缓存使用,比较陌生。比如是否支持Redis或者可以自己开发支持。是否支持针对部分需要加入缓存的方法配置,而不是所有的hibernate实体都加入缓存。可能我这种方法对于二级缓存来说,抛开代码差距,也是殊途同归的东西。

这几天工作中,突然遇到了对于有些个实体类,需要被缓存起来。但是这些个实体类数目庞大, 初始化加载的话,太耗费时间。所以初步的方案就是先查缓存,缓存没有就查询数据库,查完数据库再放入缓存。同时也方便设置过期时间。

但是针对目前的项目来说,Dao是作为独立的Maven Module,Redis也是独立的Maven Module,相互耦合的话,代码变得难以维护,结构不清晰。所以引入了注解,然后在Redis项目中,针对注解做AOP,这样的话,没有用到缓存的项目,就可以忽略这样的注解。如果用到了,可以自动加入缓存。

 

注解代码:

package com.ns.annotation;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; import java.util.concurrent.TimeUnit; /** * 只能注解dao里面对应的get方法,传递的参数作为hashkey,返回的值作为value * @author Han */ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Cached { /** * redis key * @return */ String key(); /** * 过期时间,默认为0即永不过期 * @return */ long timeout() default 0L; /** * 时间单位,默认为秒 * @return */ TimeUnit timeunit() default TimeUnit.SECONDS; }

 

 

Aop切面代码

package com.ns.redis.aop;import java.lang.reflect.Method;import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; import org.apache.commons.collections.MapUtils; import org.apache.commons.lang.ArrayUtils; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DataAccessException; import org.springframework.data.redis.connection.RedisConnection; import org.springframework.data.redis.core.RedisCallback; import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.stereotype.Component; import org.springframework.util.Assert; import com.ns.annotation.Cached; import com.ns.redis.dao.base.BaseRedisDao; /** * 对dao的getbean的缓存处理 * @author Han */ @Aspect @Component public class AutoRedisCached extends BaseRedisDao
{ /* * 约束任意包下的包含Dao的类的任意方法,并且被cached注解 */ @Pointcut("execution(* *..*Dao*.*(*,..) && @annotation(com.ns.annotation.Cached))") private void cacheMethod(){} @Around("cacheMethod()") public Object doArround(ProceedingJoinPoint pjp) throws Throwable{ Object[] args = pjp.getArgs(); //定义序列化器 final RedisSerializer
keySerializer = getKeySerializer(); final RedisSerializer
hashValueSerializer = getHashValueSerializer(); final RedisSerializer hashKeySerializer = getHashKeySerializer(); //序列化参数,作为hashkey byte [] hashkeyBytesTmp = null; if(args.length == 1){ hashkeyBytesTmp = hashKeySerializer.serialize(args[0]); }else{ hashkeyBytesTmp = new byte[0]; for(Object arg : args){ hashkeyBytesTmp = ArrayUtils.addAll(hashkeyBytesTmp, hashKeySerializer.serialize(arg)); } } final byte [] hashkeyBytes = hashkeyBytesTmp; MethodSignature methodSignature = (MethodSignature) pjp.getSignature(); Method method = methodSignature.getMethod(); final Cached cacheinfo = method.getAnnotation(Cached.class); Object obj= null; obj = execute(new RedisCallback() { @Override public Object doInRedis(RedisConnection connection) throws DataAccessException { byte [] tmp = connection.hGet(keySerializer.serialize(cacheinfo.key()), hashkeyBytes); return hashValueSerializer.deserialize(tmp); } }); if(obj == null){ final Object objReturn = pjp.proceed(); if(objReturn != null){ execute(new RedisCallback
() { @Override public Boolean doInRedis(RedisConnection connection) throws DataAccessException { return connection.hSet(keySerializer.serialize(cacheinfo.key()), hashkeyBytes,hashValueSerializer.serialize(objReturn)); } }); if(cacheinfo.timeout()>0){ expire(cacheinfo.key(), cacheinfo.timeout(), cacheinfo.timeunit()); } } obj = objReturn; } //从dao获取 return obj; } }

转载地址:http://xmgdl.baihongyu.com/

你可能感兴趣的文章
真的吗?算法谋取暴利,让你多花钱
查看>>
Linux 内核测试和调试(5)
查看>>
指针与数组
查看>>
Ubuntu 14.04中修复默认启用HDMI后没有声音的问题
查看>>
《C++面向对象高效编程(第2版)》——1.12 OOP 范式和语言
查看>>
《Java遗传算法编程》—— 1.4 进化计算的优势
查看>>
《R语言数据挖掘》——2.3 混合关联规则挖掘
查看>>
Commons IO 官方文档
查看>>
《精通Linux设备驱动程序开发》——第1章 引言 1.1演进
查看>>
如何使用 Kali Linux 黑掉 Windows
查看>>
《趣题学算法》—第0章0.4节算法的正确性
查看>>
《iOS 8案例开发大全》——实例008 实现断点调试
查看>>
Android优化系列一: 日志清理
查看>>
python 下载 图片、音乐、视频 和 断点续传
查看>>
《C语言及程序设计》程序阅读——程序的多文件组织
查看>>
关于大数据的十个有力事实
查看>>
柯里化的前生今世(三):语言和同像性
查看>>
文本挖掘之特征选择(Python版)
查看>>
Scala入门到精通——第三节 Array、List
查看>>
希腊字母表
查看>>