import java.lang.annotation.*;
/
* 元注解 用来标识查询数据库的方法
*/
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface UseMemCache {
/
* 缓存超时时间控制,> 0 则做超时控制
* @return
*/
int expireSeconds() default 30;
}
=================================================
/
* AOP实现cache缓存处理(缓存到静态对象)
*
* @decr
* @author jlchent
* @date 2018年11月03日
*
*/
@Component
@Aspect
public class MemCacheAspect {
private static final Logger logger = LoggerFactory.getLogger(MemCacheAspect.class);
/
* 数据缓存
*/
private static Hashtable<String, Object> dataTable = new Hashtable<>();
/
* 超时控制
*/
private static Hashtable<String, Long> timeoutTable = new Hashtable<>();
/
* 拦截所有元注解cacheCache注解的方法
*/
@Pointcut("@annotation(cn.com.framework.annotation.UseMemCache)")
public void pointcutMethod() {
}
private String saveObjToMem(String cacheKey, Object obj, int expireSeconds){
dataTable.put(cacheKey, obj);
Long expireTime = System.currentTimeMillis() + expireSeconds*1000;
timeoutTable.put(cacheKey, expireTime);
return "OK";
}
private String saveObjToMem(String cacheKey, Object obj){
dataTable.put(cacheKey, obj);
return "OK";
}
private Object getObjFromMem(String cacheKey) {
Long expireTime = timeoutTable.get(cacheKey);
Long currentTime = System.currentTimeMillis();
if (null != expireTime && currentTime > expireTime) {
过期清空
dataTable.remove(cacheKey);
timeoutTable.remove(cacheKey);
return null;
}else
return dataTable.get(cacheKey);
}
/
* 环绕处理,先从cache里获取缓存,查询不到,就通过method查询, 然后再保存到cache缓存里
*
* @param joinPoint
* @return
* @throws Throwable
*/
@Around("pointcutMethod()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
前置:从cache里获取缓存
先获取目标方法参数
long startTime = System.currentTimeMillis();
Object[] args = joinPoint.getArgs();
String pragrm = "";
if (args != null && args.length > 0) {
for (int i = 0; i < args.length; i++) {
pragrm = "_"+pragrm + String.valueOf(args[i]) ;
}
}
获取目标方法所在类
String target = joinPoint.getTarget().toString();
String className = target.split("@")[0];
获取目标方法的方法名称
String methodName = joinPoint.getSignature().getName();
int expireSeconds = 0;
try {
Class<?> clz = Class.forName(className);
Class<?>[] classes = null;
if (args != null && args.length > 0) {
classes = new Class[args.length];
for (int i = 0; i < classes.length; i++) {
classes[i] = args[i].getClass();
}
}
Method method = clz.getMethod(methodName, classes);
UseMemCache useMemCache = method.getAnnotation(UseMemCache.class);
if (useMemCache != null && useMemCache.expireSeconds() > 0) {
expireSeconds = useMemCache.expireSeconds();
}
} catch (ClassNotFoundException e1) {
e1.printStackTrace();
logger.warn("类包"+className+"不存在", e1);
throw e1;
}
cache中key格式: applId:方法名称
String cacheKey = className + "." + methodName + pragrm;
Object obj = getObjFromMem(cacheKey);
if (obj != null) {
logger.debug("cache的VALUE值类型:" + obj.getClass().getName());
return obj;
}
long endTime = System.currentTimeMillis();
logger.debug("cache缓存AOP处理所用时间(毫秒):" + (endTime - startTime));
logger.info("没有从cache查到数据");
logger.info("开始通过Method查询数据");
obj = joinPoint.proceed();
if (obj == null) {
logger.info("获取到null数据");
return null;
}
后置:将数据库查到的数据保存到cache
String code = "";
if (expireSeconds > 0) {
code = saveObjToMem(cacheKey, obj, expireSeconds);
} else {
code = saveObjToMem(cacheKey, obj);
}
if "OK").equals(code {
logger.info("数据成功保存到cache缓存!!!**");
logger.info("MeM的KEY值:" + cacheKey);
logger.info("cache的VALUE值类型:" + obj.getClass().getName());
}
return obj;
}
}