今天梳理了下项目中使用的价格aop相关的点,今天用些时间抽离出来,给大家学习,代码是我脱敏之后的,为了安全为了我的前途我只能这样,大家学到其中的技术点就可以
实例1 接口防重
在互联网中都是前后端分离,后端提供的api怎么防重?
原理:首先利用分布式锁,使用redis的key的实效性,
当这个锁获取不到证明key还有效不能进行访问,直接抛异常,如果不存在key获取锁成功,进行相应的方法
@Around("@annotation(com.wfg.aop.PreventDuplicateRequest)")
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
Object target = joinPoint.getTarget();
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
PreventDuplicateRequest annotation = method.getAnnotation(PreventDuplicateRequest.class);
String key = annotation.key();
if (StringUtils.isBlank(key)) { //未设置key的情况下
Object[] args = joinPoint.getArgs();
key = generateKey(annotation, target, signature, args);
}
if (StringUtils.isBlank(key)) {
return joinPoint.proceed();
}
long ttlInMs = annotation.duration();
//执行锁
boolean locked = false;
/* try {
//设置解锁key
locked = PreventDuplicateLock.acquire(PREFIX + key, ttlInMs);
if (locked) {
return joinPoint.proceed();
} else {
throw new DuplicatedRequestException();
}
} finally {
//设置解锁key和解锁时间
// 释放锁
if (locked) {
PreventDuplicateLock.release(PREFIX + key);
}
}*/
return null;
}
注意:但凡项目中使用不会这么简单的使用,代码仅仅是代码片段,不能运行,仅仅提供一个学习的思路而已
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface PreventDuplicateRequest {
@AliasFor("keyexpr")
String value() default "";
String key() default "";
/**
* key 表达式
* @return
*/
String keyexpr() default "";
/**
* 防重时间, 一定时间内持有指定key的锁, 单位ms 毫秒
* 默认5000 ms
*/
long duration() default 5000;
/**
* 是否使用集中式锁(redis 实现), 默认true; 否则使用并发Map简单实现, 即单机本地防重
* @return
*/
boolean distributed() default true;
}
介入监控系统
互联网公司针对监控系统要求比较高,基本把所有的方法都进行监控,出现问题容易排查,原理是一样的
原理:
1.定义切点,controller,service层所有的方法介入,以及自定义注解等方式
2.使用环绕通知Around在方法调用前接入监控系统和方法调用完成接入监控系统