文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

JAVA开发(AOP之ProceedingJoinPoint)

2023-09-20 10:32

关注

我们在开发过程中经常使用到自定义注解来实现在一些类或者方法执行过程中切面,统一实现某些业务操作。例如自定义注解

import java.lang.annotation.Documented;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;import java.util.Map;@Documented@Target({ElementType.METHOD,ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)public @interface CtgEncrypt {        Class paramType() default Map.class;        String securityType() default "AES";        String reType() default "";}

注解一般开门见山,说我要干一个什么事情。使用@interface来修饰。例如上面这个注解就是用来对方法上的参数进行加密的。

@Target({ElementType.METHOD,ElementType.TYPE})

这个代码作用的METHOD(方法)上

@Retention(RetentionPolicy.RUNTIME)

这个代码代码运行时执行操作。

自定义的注解需要实现它功能才能用,不是注解了注解本身就有这个功能,没那么强大。

第二步实现注解功能。

import java.util.Arrays;import java.util.List;import java.util.Map;import javax.servlet.http.HttpServletRequest;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.beans.factory.annotation.Value;import org.springframework.stereotype.Component;import org.springframework.util.AntPathMatcher;import com.alibaba.fastjson.JSONObject;import cn.ctg.common.response.ResponseCode;import cn.ctg.common.response.ResponseData;import cn.ctg.common.util.UserTokenUtils;import cn.ctg.common.util.XssUtils;import cn.hutool.json.JSONUtil;@Aspect@Componentpublic class SecurityAspect {    @Value("${keys.aeskey:-1}")    private String AES_KEY;    @Value("${keys.jwtkey:-1}")    private String JWT_KEY;    @Value("${xss.url:-1}")    private String xxsUrl;    private AntPathMatcher antPathMatcher = new AntPathMatcher();        @Pointcut("@annotation(cn.ctg.common.util.security.CtgDecrypt) || @annotation(cn.ctg.common.util.security.CtgEncrypt)")    public void pointCut(){ }        @Around("execution(* cn.ctg.*.controller.*.*(..))")    public Object doAroundHtml(ProceedingJoinPoint joinPoint) throws Throwable {        Object[] args = joinPoint.getArgs();        HttpServletRequest httpServletRequest = UserTokenUtils.getHttpServletRequest();        String requestURI = httpServletRequest.getRequestURI();        String[] split = xxsUrl.split("\\|");        if(split==null){            return joinPoint.proceed(args);        }        if(pathMatcher(Arrays.asList(split),requestURI)) {            for (int i = 0; i < args.length; i++) {                Object arg = args[i];                Map map = JSONUtil.parseObj(JSONObject.toJSONString(arg));                for (Map.Entry entry : map.entrySet()) {                    if (XssUtils.isStripXSS(entry.getValue().toString())) {                        ResponseData responseData = ResponseData.error(ResponseCode.XSS_CODE_ERROR);                        return responseData;                    }                }            }        }        return joinPoint.proceed(args);    }        @Around("pointCut()")    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {        //执行方法,获取返回值        Object result = joinPoint.proceed();        String data = JSONUtil.toJsonStr(((ResponseData) result).getData());        if(data.equals("{}")){            data = String.valueOf(((ResponseData) result).getData());        }                ((ResponseData) result).setEncrypt(true);        return result;    }    // 白名单查询    private boolean pathMatcher(List urlList, String requestUri) {        for (String url : urlList) {            if (antPathMatcher.match(url, requestUri)) {                return true;            }        }        return false;    }}  

代码中的这一句 @Pointcut("@annotation(cn.ctg.common.util.security.CtgDecrypt) || @annotation(cn.ctg.common.util.security.CtgEncrypt)")

就是用来实现CtgEncrypt这个注解的

再使用@Around("pointCut()")进行方法环绕。实现注解的动作。

        @Around("pointCut()")    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {        //执行方法,获取返回值        Object result = joinPoint.proceed();        String data = JSONUtil.toJsonStr(((ResponseData) result).getData());        if(data.equals("{}")){            data = String.valueOf(((ResponseData) result).getData());        }                ((ResponseData) result).setEncrypt(true);        return result;    }

这是我们看到一个重要类型ProceedingJoinPoint。执行当前切点的意思

这里就通过源码看看ProceedingJoinPoint能做什么东西。

package org.aspectj.lang;import org.aspectj.runtime.internal.AroundClosure;public interface ProceedingJoinPoint extends JoinPoint {        void set$AroundClosure(AroundClosure arc);         default void stack$AroundClosure(AroundClosure arc) {         throw new UnsupportedOperationException();     }        public Object proceed() throws Throwable;        public Object proceed(Object[] args) throws Throwable;}

从源码上继承了JoinPoint

public Object proceed() throws Throwable;

Proceed with the next advice or target method invocation

继续执行下一个通知或目标方法调用

获取当前正在执行的对象(如果不可用则为空——例如静态上下文)

Object getThis();

获取目标对象(如果没有,则为空)

Object getTarget();

获取这个连接点上的参数

Object[] getArgs();

获取连接点上的签名。

Signature getSignature();

来源地址:https://blog.csdn.net/dongjing991/article/details/128654007

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 资料下载
  • 历年真题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容
咦!没有更多了?去看看其它编程学习网 内容吧