缓存服务器Redis 04 AOP实现Redis缓存服务

微信扫一扫,分享到朋友圈

缓存服务器Redis 04 AOP实现Redis缓存服务

在上文中,我们虽然在业务层service中完成了代码的实现.但是该代码不具有复用性.如果换了其他的业务则需要重新编辑.

并且由于缓存的代码写在业务层service中,所以代码的耦合性高,不方便以后的扩展.

所以我们从代码复用以及降低代码的耦合性的方面使用AOP来实现redis缓存.

AOP

AOP即面向切面编程–在不改动原有代码的基础上,对业务进行增强.

AOP = 切入点表达式 + 通知方法

专业术语:

1.连接点: 在执行正常的业务过程中满足了切入点表达式时进入切面的点.(织入) 多个

2.通知: 在切面中执行的具体的业务(扩展) 方法

3.切入点: 能够进入切面的一个判断 if判断 一个

4.目标方法: 将要执行的真实的业务逻辑.

通知方法

分类:

1.前置通知(@Before): 目标方法执行之前执行

2.后置通知(@After): 目标方法执行之后执行

3.异常通知(@AfterThrowing): 目标方法执行之后抛出异常时执行

4.最终通知(@AfterReturning): 不管什么时候都要执行的方法.

说明:上述的四大通知类型 不能控制目标方法是否执行
.一般使用上述的四大通知类型,都是用来记录程序的 执行状态
.

5. 环绕通知(@Around)
: 在目标方法执行前后都要执行的通知方法
. 控制目标方法是否执行.并且环绕通知的功能最为强大.

环绕通知是最为常用的.

切入点表达式

分类:

1. bean(bean的id)
类名首字母小写 匹配1个类

2.within(包名.类名) 按包路径匹配类 匹配多个类

上述表达式是粗粒度的控制,按类匹配.

3.execution(返回值类型 包名.类名.方法名(参数列表))

4. @annotation(包名.注解名)
按注解进行拦截.

上述是细粒度的控制.

bean和@annotation较为常用

实现Redis缓存

业务分析

1.自定义注解CacheFind 主要被注解标识的方法,则开启缓存的实现.

2.为了将来区分业务,需要在注解中标识key属性,由使用者自行填写.

3.为了用户提供数据超时功能.

自定义注解@CacheFind

@Retention(RetentionPolicy.RUNTIME) //该注解运行时有效
@Target({ElementType.METHOD})       //对方法有效
public @interface CacheFind {
String key();               //该属性为必须添加
int seconds() default 0;    //设定超时时间 默认不超时
}

编写CacheAOP类

package com.jt.aop;
import com.jt.annotation.CacheFind;
import com.jt.util.ObjectMapperUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import redis.clients.jedis.Jedis;
import java.util.Arrays;
@Component
@Aspect
public class RedisAOP {
//注入缓存reids对象
@Autowired
private Jedis jedis;
//@Pointcut("@annotation(com.jt.annotation.CacheFind)")
//public void doRedisPointCut(){}
/**
* 拦截@CacheFind注解表示的方法
* 通知选择: 缓存的实现应该选用环绕通知
* 步骤:
*  1.动态生成key 用户填写的key+用户提交的参数
*/
@Around("@annotation(cacheFind)")
public Object around(ProceedingJoinPoint joinPoint, CacheFind cacheFind){
try {
Object result = null;
//1.如何动态获取用户在注解中填写的数据
String prekey = cacheFind.key();
//2.动态获取目标方法中的参数  将数组转化为字符串
String args = Arrays.toString(joinPoint.getArgs());
String key = prekey + "::" + args; //"ITEM_CAT_PARENTID::[0]"
//3.查询缓存中查询
//4.判断json中是否有值
if (jedis.exists(key)) {  //先获取json数据
String json = jedis.get(key);
//动态获取目标方法的返回值类型?? 向上造型 不用强转   向下造型
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
Class target = methodSignature.getReturnType();
//7.进入代表程序中有值,将json转为对象
result = ObjectMapperUtil.toObject(json, target);
System.out.println("AOP实现缓存查询!!!!");
}else {
//5.若缓存中没有查询数据库
result = joinPoint.proceed(); //执行目标方法,获取返回值结果
System.out.println("AOP执行数据库操作");
//6.将数据存到redis中
//先转为json格式
String json = ObjectMapperUtil.toJSON(result);
if(cacheFind.seconds()>0){  //判断是否需要超时时间
jedis.setex(key, cacheFind.seconds(), json);
}else {
jedis.set(key, json);
}
}
return result;
}catch (Throwable e){
e.printStackTrace();
throw new RuntimeException(e);
}
}
}

注意

关于环绕通知参数的说明:

1.连接点必须位于通知方法参数的第一位

2.其他四大通知类型不可以添加ProceedingJoinPoint对象,可以添加JointPoint对象

JoinPoint使用

/**
* 要求: 拦截注解方法
* 打印:
*      1.打印目标对象的类型
*      2.打印方法的参数
*      3.获取目标对象的名称及方法的名称
* @param joinPoint
*/
@Before("@annotation(com.jt.anno.CacheFind)")
public void before(JoinPoint joinPoint){
Object target = joinPoint.getTarget();  //获取目标对象
Object[] args = joinPoint.getArgs();    //获取方法参数的
String targetName =
joinPoint.getSignature().getDeclaringTypeName(); //获取目标对象的名称
//获取目标对象的类型
Class targetClass = joinPoint.getSignature().getDeclaringType();
//获取目标方法的名称
String methodName = joinPoint.getSignature().getName();
System.out.println(target);
System.out.println(args);
System.out.println(targetName);
System.out.println(targetClass);
System.out.println(methodName);
}

微信扫一扫,分享到朋友圈

缓存服务器Redis 04 AOP实现Redis缓存服务

宜家被点名:两批次儿童家具不合格

上一篇

分布式层次GPU参数服务器架构

下一篇

你也可能喜欢

缓存服务器Redis 04 AOP实现Redis缓存服务

长按储存图像,分享给朋友