利用AOP中采用注解的形式实现业务缓存处理

利用AOP中采用注解的形式实现业务缓存处理


通知选择:环绕通知.利用注解定义切入点表达式.

业务思路:当执行方法时如果该方法添加了@Cache()则进行AOP业务执行.

  首先根据key(????)查询redis缓存.

  null: 应该执行业务方法.,获取返回值之后添加缓存.

!null:将缓存数据转化为返回值对象.之后返回.


通用做法:

key:按照方法名称+第一个参数拼接动态的Key

findAll();

//定义一个查询的注解

@Retention(RetentionPolicy.RUNTIME)

@Target({ElementType.METHOD}) //注解的作用范围

public @interface Cache_Find {

String key()    default "";//接收用户key值

KEY_ENUM keyType() default KEY_ENUM.AUTO;//定义key类型

int secondes()    default 0; //永不失效

}

 编辑AOP

@Component //将对象交给spring容器管理

@Aspect //标识这是一个切面  切面=切入点表达式+通知

@Slf4j

public class RedisAspect {


//表示当spring容器启动时不会立即注入对象???

@Autowired(required = false)

private JedisCluster jedisCluster;

/**

*规定:

 * 1.环绕通知必须使用ProceedingJoinPoint

 * 2.如果通知中有参数joinPoint.必须位于第一位

 * @param joinPoint

 * @return

 */

@SuppressWarnings("unchecked")

//问题1:如何获取注解中的属性?

//该切入点表达式 规定只能获取注解类型 用法名称必须匹配

@Around(value="@annotation(cache_Find)")

public Object around(ProceedingJoinPoint joinPoint,Cache_Find cache_Find) {

//1.动态获取key

String key = getKey(joinPoint,cache_Find);


//2.从redis中获取数据

String resultJSON = jedisCluster.get(key);

Object resultData = null;

try {

//3.判断数据是否有值

if(StringUtils.isEmpty(resultJSON)) {

//3.1表示缓存中没有数据,则查询数据库(调用业务方法)

resultData = joinPoint.proceed();

//3.2将数据保存到缓存中

String json = ObjectMapperUtil.toJSON(resultData);

//3.3判断当前数据是否有失效时间

if(cache_Find.secondes()==0) {

jedisCluster.set(key, json);

}else {

jedisCluster.setex(key,cache_Find.secondes(), json);

}

System.out.println("AOP查询数据库成功!!!");

}else {

//4.表示redis缓存中有数据

Class returnType = getClass(joinPoint);

resultData = ObjectMapperUtil.toObject(resultJSON,returnType);

System.out.println("AOP查询缓存!!!!!!");

}

} catch (Throwable e) {

e.printStackTrace();

log.error(e.getMessage());

throw new RuntimeException(e);

}

return resultData;

}

key的定义

/**

* key的定义规则如下:

 * 1.如果用户使用AUTO.则自动生成KEY 方法名_第一个参数

 * 2.如果用户使用EMPTY,使用用户自己的key

 * @param joinPoint

 * @param cache_Find

 * @return

 */

private String getKey(ProceedingJoinPoint joinPoint, Cache_Find cache_Find) {

//1.判断用户选择类型

if(KEY_ENUM.EMPTY.equals(cache_Find.keyType())) {

return cache_Find.key();

}

//2.表示用户动态生成key  findITemCat::0

String methodName = joinPoint.getSignature().getName();

String arg0 = String.valueOf(joinPoint.getArgs()[0]);

return methodName+"::"+arg0;

}

/**

*表示获取方法对象的返回值类型

 * @param joinPoint

 * @return

 */

private Class getClass(ProceedingJoinPoint joinPoint) {

MethodSignature signature = (MethodSignature)joinPoint.getSignature();

return signature.getReturnType();

}

}

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容