spring 重复注解和aop拦截 spring 重复注解和aop拦截的实现示例
花开浪漫拾 人气:0想了解spring 重复注解和aop拦截的实现示例的相关内容吗,花开浪漫拾在本文为您仔细讲解spring 重复注解和aop拦截的相关知识和一些Code实例,欢迎阅读和指正,我们先划重点:spring,重复注解,spring,aop拦截,下面大家一起来学习吧。
前言:
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; /** * 接口限流 * * @author wulm */ @Repeatable(RequestLimit.RequestLimitPack.class) @Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface RequestLimit { /** * 最大次数,比如 每分钟100次、每小时500次、每天1000次 */ int maxTimes(); /** * 频率更新时间,比如 60:每分钟、 3600:每小时、 86400:每天 **/ 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) { //代码忽略...... } }
加载全部内容