·AOP之注解类型
程序员文章站
2022-04-30 15:29:34
...
aop的实现,可以基于 cglib 和jdk proxy 。Java中默认使用jdk proxy。
本文是分布式项目中一个Redis缓存实例
首先我们来创建一个注解类@interface
@Target(ElementType.METHOD) //标识注解对方法生效
@Retention(RetentionPolicy.RUNTIME) //标识当前注解的生命周期
public @interface CacheFind {
/**
*
* 要求:key不同的业务一定不能重复.
*
* 规则:
* key值默认为"",
* 如果用户添加了key.则使用用户的
* 如果用户没有添加key,
* 生成策略: 包名.类名.方法名::第一个参数
*
* 添加时间: 如果不为0则需要数据添加过期时间 setex
*/
String key() default "";
int seconds() default 0;
}
@Target(ElementType.METHOD) //标识注解对方法生效
@Retention(RetentionPolicy.RUNTIME) //标识当前注解的生命周期
这两个注解针对环境变更
下面再创建一类标注@Aspect
//定义缓存切面
@Component //万能注解 交给容器管理
@Aspect //自定义切面
public class CacheAOP {
@Autowired(required = false)
private JedisCluster jedis;
/**
* 环绕通知的语法
* 返回值类型: 任意类型用Obj包裹
* 参数说明: 必须包含并且位置是第一个
* ProceedingJoinPoint
* 通知标识:
* [email protected]("切入点表达式")
* [email protected](切入点())
*/
@SuppressWarnings("unchecked")
@Around("@annotation(cacheFind)")
public Object around(ProceedingJoinPoint joinPoint,CacheFind cacheFind) {
//定义数据的返回值
Object result = null;
String key = getKey(joinPoint,cacheFind);
String value = jedis.get(key);
if(StringUtils.isEmpty(value)) {
try {
//缓存数据为null.查询数据库
result = joinPoint.proceed();
String json = ObjectMapperUtil.toJSON(result);
if(cacheFind.seconds() >0) {
//需要添加超时时间
jedis.setex(key,cacheFind.seconds(), json);
}else {
jedis.set(key, json);
}
System.out.println("AOP实现数据库查询!!!!!");
} catch (Throwable e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}else {
//缓存数据不为null 需要将json转化为对象
Class returnType = getReturnType(joinPoint);
result = ObjectMapperUtil.toObject(value, returnType);
System.out.println("AOP实现缓存查询!!!!!");
}
return result;
}
}
JSON转换的工具类(需要jackson)
public class ObjectMapperUtil {
private static final ObjectMapper MAPPER = new ObjectMapper();
//1.将对象转化为json
//如果程序有异常,转化为运行时异常
public static String toJSON(Object obj) {
String json = null;
try {
json = MAPPER.writeValueAsString(obj);
} catch (JsonProcessingException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
return json;
}
/**
* 要求:用户传递什么类型,返回什么对象.
* 方案: 使用泛型对象实现!!!
* @param json
* @param targetClass
* @return
*/
public static <T> T toObject(String json,Class<T> targetClass) {
T t = null;
try {
t = MAPPER.readValue(json, targetClass);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
return t;
}
}