前言:
1:jdk1.8开始支持重复注解@Repeatable实现
2:aop拦截需要拦截当前注解和@Repeatable指向的包装注解才可以完全拦截到,因为:1.当在在方法上只有一个注解时,aop拦截认为是非包装类型注解。2.当方法上有多个重复注解时,aop拦截认为是包装类型注解。
重复注解实现方式(RequestLimit为原始注解,RequestLimitPack为包装注解):
import java.lang.annotation.ElementType;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Repeatable(RequestLimit.RequestLimitPack.class)
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface RequestLimit {
int maxTimes();
int seconds();
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface RequestLimitPack {
RequestLimit[] value();
}
}
重复注解效果:
aop拦截(设置了两处@Around):
@Aspect
@Configuration
public class RequestLimitAop {
private static final Logger LOGGER = LoggerFactory.getLogger(RequestLimitAop.class);
public static final String Redis_SPLIT_STR = "#";
public static final String SUB_MODULE = "api";
@Pointcut(value = "@annotation(com.zxy.product.hr.sync.WEB.config.annotation.RequestLimit)")
public void pointcut() {
}
@Pointcut(value = "@annotation(com.zxy.product.hr.sync.web.config.annotation.RequestLimit" +
".RequestLimitPack)")
public void pointcutRequestLimitOuts() {
}
@Around(value = "pointcut()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
// 获取拦截的方法名
MethodSignature msig = (MethodSignature) joinPoint.getSignature();
// 获取到注解
RequestLimit requestLimit = msig.getMethod().getAnnotation(RequestLimit.class);
ResultInfo resultInfo = checkFrequency(requestLimit, false);
if (ResultInfo.isSuccess(resultInfo)) {
// 继续执行方法
return joinPoint.proceed();
} else {
return resultInfo;
}
}
@Around(value = "pointcutRequestLimitOuts()")
public Object aroundRequestLimitOuts(ProceedingJoinPoint joinPoint) throws Throwable {
// 获取拦截的方法名
MethodSignature msig = (MethodSignature) joinPoint.getSignature();
// 获取到注解
RequestLimit.RequestLimitPack requestLimitPack = msig.getMethod()
.getAnnotation(RequestLimit.RequestLimitPack.class);
for (RequestLimit requestLimit : requestLimitPack.value()) {
ResultInfo resultInfo = checkFrequency(requestLimit, false);
if (!ResultInfo.isSuccess(resultInfo)) {
//失败立即返回
return resultInfo;
}
}
//没问题则继续执行
return joinPoint.proceed();
}
public static ResultInfo checkFrequency(RequestLimit requestLimit, boolean isInnerApi) {
//代码忽略......
}
}
标签:示例,spring,RequestLimitPack,RequestLimit,annotation,aop,注解,拦截,public
From: https://www.cnblogs.com/dituirenwu/p/17096314.html