aop切面和自定义注解

时间:2021-11-30
本文章向大家介绍aop切面和自定义注解,主要包括aop切面和自定义注解使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
package com.lanfu.storehouse.annotation;
//先自定义一个注解
import java.lang.annotation.*; @Inherited @Documented @Target({ElementType.FIELD,ElementType.TYPE,ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface AccessLimit { //标识 指定sec时间段内的访问次数限制 int limit() default 5; //标识 时间段 int sec() default 5; }

写一个切面

package com.lanfu.storehouse.aspect;

import com.lanfu.storehouse.annotation.AccessLimit;
import com.lanfu.storehouse.common.base.ErrorCodeEnum;
import com.lanfu.storehouse.common.exception.BaseBussinessException;
import com.lanfu.storehouse.common.util.IpAddressUtil;
import com.lanfu.storehouse.common.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

@Aspect
@Component
@Slf4j
public class AccessLimitAspectAdvice {

    @Pointcut("@annotation(com.lanfu.storehouse.annotation.AccessLimit)")
    private void entryPoint(){
    }

    @Around("entryPoint()&& @annotation(accessLimit)")
    public Object accessLimit(ProceedingJoinPoint joinPoint, AccessLimit accessLimit) throws Throwable {
        //获取HttpServletRequest
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) requestAttributes;
        HttpServletRequest request = servletRequestAttributes.getRequest();
        //获取注解中的参数
        int limit = accessLimit.limit();
        int sec = accessLimit.sec();
        //使用ip加接口作为key存到redis中
        String key = IpAddressUtil.getIpAddr(request) + request.getRequestURI();
        Integer maxLimit = (Integer) RedisUtil.get(key);
        if (maxLimit == null) {
            //set时一定要加过期时间
            RedisUtil.set(key, 1, sec);
        } else if (maxLimit < limit) {
            RedisUtil.set(key, maxLimit + 1, sec);
        } else {
            throw new BaseBussinessException(ErrorCodeEnum.GW10019013);
        }
        System.out.println("joinPoint = " + joinPoint.toString());
        System.out.println("joinPoint = " + joinPoint.proceed().toString());
        return joinPoint.proceed();
    }
}

使用

    @RequestMapping(method = RequestMethod.POST, value = "/apiCallBack")
    @ResponseBody
    @AccessLimit(limit = 10,sec = 5)
    public BaseResult apiCallBack(@RequestBody Map map, HttpServletRequest httpServletRequest){
        System.out.println(map.toString());
//        String appId = requestMessageVo.getAppId();
//        String content = requestMessageVo.getContent();
//        Long timestamp = requestMessageVo.getTimestamp();
//        String concatString = appId+"507f513353702b50c145d5b7d138095c"+content+timestamp;
//        String sign = requestMessageVo.getSign();
//        String md5String = MD5Util.md5(concatString);
//        if (!md5String.equals(sign)){
//            throw new BaseBussinessException(ErrorCodeEnum.GW10019002);
//        }
//        System.out.println("===回调参数==="+content);
        return BaseResult.error();
    }
//打印出来的东西。
joinPoint = execution(BaseResult com.lanfu.storehouse.controller.GuCangAPIController.apiCallBack(Map,HttpServletRequest))
joinPoint = com.lanfu.storehouse.common.base.BaseResult@39924a6f

原文地址:https://www.cnblogs.com/zhuxiang1029/p/15624658.html