Spring面向切面编程(AOP)的简单实例

1.编写切面代码
 

@Slf4j
@Aspect
@Component
public class RateLimitAspect {
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Around("@annotation(rateLimit)")
    public Object rateLimitAdvice(ProceedingJoinPoint joinPoint, RateLimit rateLimit)  {
        String methodName = joinPoint.getSignature().toShortString();
        String key = "rate_limit:" + methodName;

        // 从Redis中获取接口调用次数
        String countStr = redisTemplate.opsForValue().get(key);
        int count = (countStr != null) ? Integer.parseInt(countStr) : 0;

        // 判断是否超过限流阈值
        if (count >= rateLimit.limit()) {
            throw new RuntimeException("接口调用次数超过限制");
        }

        // 调用接口方法,并将接口调用次数加一
        Object result = null;
        try {
            result = joinPoint.proceed();
            redisTemplate.opsForValue().increment(key);
        } catch (Throwable throwable) {
            log.info("接口掉用次数增加失败:{}",throwable);
        }

        return result;
    }
}

2.自定义注解

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface RateLimit {
    int limit();
}


3.应用
 

@Slf4j
@Controller
@RequestMapping("client/openInterface/pdd")
@ResponseBody
public class PddInterfaceController {
    @Resource
    PddShippingInfoFeign pddShippingInfoFeign;

    @RateLimit(limit = 40000) // 设置每日最大调用次数为40000
    @RequestMapping("/getShippingInfo")
    public PddShippingInfoResp getShippingInfo(HttpServletRequest request) {
        PddShippingInfoReq req = analizeRequest(request);
        return pddShippingInfoFeign.getShippingInfo(req);
    }

    private PddShippingInfoReq analizeRequest(HttpServletRequest request) {
        PddShippingInfoReq pddShippingInfoReq = new PddShippingInfoReq();
        try {
            pddShippingInfoReq.setPartnerId(request.getParameter("partnerId"));
            pddShippingInfoReq.setDataDigest(request.getParameter("dataDigest"));
            JSONObject parseObject = JSON.parseObject(request.getParameter("data"));
            log.info("beforeData:{}", parseObject);
            PddShippingData pdd = parseObject.toJavaObject(PddShippingData.class);
            pddShippingInfoReq.setData(pdd);
            log.info("lastDate:{}", pddShippingInfoReq.getData());
        } catch (Exception e) {
            log.error("PddInterfaceController.PddShippingInfoReq req:{}", request, e);
        }
        return pddShippingInfoReq;
    }
}

4.前置通知
 

@Component
@Aspect
@Slf4j
public class UserInfoAspect {
    @Pointcut("execution(* com.yunda.controller..*.*(..)) && !execution(* com.yunda.controller.app..*.*(..))")
    public void setUserInfo() {
    }

    @Resource
    private IdassUserPermissionService idaasUserPermissionServiceImpl;

    private Pattern pattern = Pattern.compile("^9\\d*$");

    @Before("setUserInfo()")
    public void doBefore(JoinPoint joinPoint) throws Exception {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
        String uri = request.getRequestURI();
        // 排除一些特殊的url
        if (null != uri && uri.contains("app/dzg")) {
            return;
        }

        boolean needSetBaseInfoFlag = false;

        Object[] args = joinPoint.getArgs();
        if (ObjectUtils.isNotEmpty(args)) {
            for (Object arg : args) {
//                log.info("arg:{}", arg.getClass().getName());
                if (arg instanceof List) {
                    List list = (List) arg;
                    for (Object obj : list) {
                        if (obj instanceof LoginUserInfo) {
                            needSetBaseInfoFlag = true;
                            break;
                        }
                    }
                }
                if (arg instanceof LoginUserInfo &&
                        (((LoginUserInfo) arg).getLoginSiteId() == null
                                || ((LoginUserInfo) arg).getLoginUserId() == null )) {
                    needSetBaseInfoFlag = true;
                    break;
                }
            }
            if (!needSetBaseInfoFlag) {
                log.info("need not user info");
                return;
            }
            log.info("need user info");
            CasUserInfo userInfo = CasUserUtils.getUserInfo();
            if (userInfo != null) {
                String orgCode = userInfo.getOrgCode() + "";
                Long orgId;
                //判断如果有9就不添加
                orgId = Long.valueOf(String.format("9%s", orgCode));
                //获取权限
                RoleAndPermission roleAndPermission = (RoleAndPermission) idaasUserPermissionServiceImpl.getPermission(userInfo);
                for (Object arg : args) {
                    if (arg instanceof List) {
                        List list = (List) arg;
                        for (Object obj : list) {
                            if (obj instanceof LoginUserInfo) {
                                ((LoginUserInfo) obj).setLoginUserId(Long.valueOf(userInfo.getUserId()));
                                ((LoginUserInfo) obj).setLoginUserName(userInfo.getUserName());
                                ((LoginUserInfo) obj).setLoginSiteId(orgId);
                                ((LoginUserInfo) obj).setLoginSiteName(userInfo.getOrgName());
                                ((LoginUserInfo) obj).setPermission(roleAndPermission.getPermission());
                                ((LoginUserInfo) obj).setRoles(roleAndPermission.getRoles());
                            }
                        }
                    }
                    if (arg instanceof LoginUserInfo) {
                        log.info("打印请求头:{}", request.getHeader("partLoginSiteId") + "-" + request.getHeader("partLoginSiteName"));
                        //判断是否有传输特殊登录网点
                        String partLoginSiteId = request.getHeader("partLoginSiteId");
                        String partLoginSiteName = request.getHeader("partLoginSiteName");
//                        String partLoginSiteId = "963001828";
//                        String partLoginSiteName = "综合处理组";
                        ((LoginUserInfo) arg).setLoginUserId(Long.valueOf(userInfo.getUserId()));
                        ((LoginUserInfo) arg).setLoginUserName(userInfo.getUserName());
                        ((LoginUserInfo) arg).setLoginSiteId(orgId);
                        ((LoginUserInfo) arg).setLoginSiteName(userInfo.getOrgName());
                        ((LoginUserInfo) arg).setPermission(roleAndPermission.getPermission());
                        ((LoginUserInfo) arg).setRoles(roleAndPermission.getRoles());
                        if (StringUtils.isNotBlank(partLoginSiteId) && StringUtils.isNotBlank(partLoginSiteName)) {
                            ((LoginUserInfo) arg).setLoginSiteId(Long.valueOf(partLoginSiteId));
                            ((LoginUserInfo) arg).setLoginSiteName(partLoginSiteName);
                        }
                    }
                }
            }

        }

    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值