当前位置:   article > 正文

JAVA开发(AOP之ProceedingJoinPoint)_proceedingjoinpoint 获取参数

proceedingjoinpoint 获取参数

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

  1. import java.lang.annotation.Documented;
  2. import java.lang.annotation.ElementType;
  3. import java.lang.annotation.Retention;
  4. import java.lang.annotation.RetentionPolicy;
  5. import java.lang.annotation.Target;
  6. import java.util.Map;
  7. @Documented
  8. @Target({ElementType.METHOD,ElementType.TYPE})
  9. @Retention(RetentionPolicy.RUNTIME)
  10. public @interface CtgEncrypt {
  11. /** 参数类型 */
  12. Class<?> paramType() default Map.class;
  13. /** 加密类型 (AES/RSA) */
  14. String securityType() default "AES";
  15. /**返回参数Request /响应参数Response */
  16. String reType() default "";
  17. }

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

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

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

@Retention(RetentionPolicy.RUNTIME)

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

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

第二步实现注解功能。

  1. import java.util.Arrays;
  2. import java.util.List;
  3. import java.util.Map;
  4. import javax.servlet.http.HttpServletRequest;
  5. import org.aspectj.lang.ProceedingJoinPoint;
  6. import org.aspectj.lang.annotation.Around;
  7. import org.aspectj.lang.annotation.Aspect;
  8. import org.aspectj.lang.annotation.Pointcut;
  9. import org.springframework.beans.factory.annotation.Value;
  10. import org.springframework.stereotype.Component;
  11. import org.springframework.util.AntPathMatcher;
  12. import com.alibaba.fastjson.JSONObject;
  13. import cn.ctg.common.response.ResponseCode;
  14. import cn.ctg.common.response.ResponseData;
  15. import cn.ctg.common.util.UserTokenUtils;
  16. import cn.ctg.common.util.XssUtils;
  17. import cn.hutool.json.JSONUtil;
  18. /**
  19. * 切面,实现注解
  20. */
  21. @Aspect
  22. @Component
  23. public class SecurityAspect {
  24. @Value("${keys.aeskey:-1}")
  25. private String AES_KEY;
  26. @Value("${keys.jwtkey:-1}")
  27. private String JWT_KEY;
  28. @Value("${xss.url:-1}")
  29. private String xxsUrl;
  30. private AntPathMatcher antPathMatcher = new AntPathMatcher();
  31. /**切面*/
  32. @Pointcut("@annotation(cn.ctg.common.util.security.CtgDecrypt) || @annotation(cn.ctg.common.util.security.CtgEncrypt)")
  33. public void pointCut(){ }
  34. /**
  35. *
  36. * @param joinPoint
  37. * @return
  38. * @throws Throwable
  39. */
  40. @Around("execution(* cn.ctg.*.controller.*.*(..))")
  41. public Object doAroundHtml(ProceedingJoinPoint joinPoint) throws Throwable {
  42. Object[] args = joinPoint.getArgs();
  43. HttpServletRequest httpServletRequest = UserTokenUtils.getHttpServletRequest();
  44. String requestURI = httpServletRequest.getRequestURI();
  45. String[] split = xxsUrl.split("\\|");
  46. if(split==null){
  47. return joinPoint.proceed(args);
  48. }
  49. if(pathMatcher(Arrays.asList(split),requestURI)) {
  50. for (int i = 0; i < args.length; i++) {
  51. Object arg = args[i];
  52. Map<String, Object> map = JSONUtil.parseObj(JSONObject.toJSONString(arg));
  53. for (Map.Entry<String, Object> entry : map.entrySet()) {
  54. if (XssUtils.isStripXSS(entry.getValue().toString())) {
  55. ResponseData<Object> responseData = ResponseData.error(ResponseCode.XSS_CODE_ERROR);
  56. return responseData;
  57. }
  58. }
  59. }
  60. }
  61. return joinPoint.proceed(args);
  62. }
  63. /** 返回参数加密*/
  64. @Around("pointCut()")
  65. public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
  66. //执行方法,获取返回值
  67. Object result = joinPoint.proceed();
  68. String data = JSONUtil.toJsonStr(((ResponseData<?>) result).getData());
  69. if(data.equals("{}")){
  70. data = String.valueOf(((ResponseData<?>) result).getData());
  71. }
  72. /** 可以根据注解选择 加密方法 防止统一*/
  73. ((ResponseData<?>) result).setEncrypt(true);
  74. return result;
  75. }
  76. // 白名单查询
  77. private boolean pathMatcher(List<String> urlList, String requestUri) {
  78. for (String url : urlList) {
  79. if (antPathMatcher.match(url, requestUri)) {
  80. return true;
  81. }
  82. }
  83. return false;
  84. }
  85. }

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

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

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

  1. /** 返回参数加密*/
  2. @Around("pointCut()")
  3. public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
  4. //执行方法,获取返回值
  5. Object result = joinPoint.proceed();
  6. String data = JSONUtil.toJsonStr(((ResponseData<?>) result).getData());
  7. if(data.equals("{}")){
  8. data = String.valueOf(((ResponseData<?>) result).getData());
  9. }
  10. /** 可以根据注解选择 加密方法 防止统一*/
  11. ((ResponseData<?>) result).setEncrypt(true);
  12. return result;
  13. }

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

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

  1. /*******************************************************************************
  2. * Copyright (c) 2005 Contributors.
  3. * All rights reserved.
  4. * This program and the accompanying materials are made available
  5. * under the terms of the Eclipse Public License v1.0
  6. * which accompanies this distribution and is available at
  7. * http://eclipse.org/legal/epl-v10.html
  8. *
  9. * Contributors:
  10. * initial implementation Alexandre Vasseur
  11. *******************************************************************************/
  12. package org.aspectj.lang;
  13. import org.aspectj.runtime.internal.AroundClosure;
  14. /**
  15. * ProceedingJoinPoint exposes the proceed(..) method in order to support around advice in @AJ aspects
  16. *
  17. * @author Alexandre Vasseur
  18. */
  19. public interface ProceedingJoinPoint extends JoinPoint {
  20. /**
  21. * The joinpoint needs to know about its closure so that proceed can delegate to closure.run().
  22. * This internal method should not be called directly, and won't be visible to the end-user when
  23. * packed in a jar (synthetic method).
  24. *
  25. * @param arc the around closure to associate with this joinpoint
  26. */
  27. void set$AroundClosure(AroundClosure arc);
  28. /**
  29. * The joinpoint needs to know about its closure so that proceed can delegate to closure.run().
  30. * This internal method should not be called directly, and won't be visible to the end-user when
  31. * packed in a jar (synthetic method). This should maintain a stack of closures as multiple around
  32. * advice with proceed are targeting a joinpoint and the stack will need to be unwound when
  33. * exiting nested advice. Passing a non null arc indicates a push, passing null indicates a pop.
  34. *
  35. * @param arc the around closure to associate with this joinpoint
  36. */
  37. default void stack$AroundClosure(AroundClosure arc) {
  38. throw new UnsupportedOperationException();
  39. }
  40. /**
  41. * Proceed with the next advice or target method invocation
  42. *
  43. * @return the result of proceeding
  44. * @throws Throwable if the invoked proceed throws anything
  45. */
  46. public Object proceed() throws Throwable;
  47. /**
  48. * Proceed with the next advice or target method invocation.
  49. *
  50. * Unlike code style, proceed(..) in annotation style places different requirements on the
  51. * parameters passed to it. The proceed(..) call takes, in this order:
  52. * <ul>
  53. * <li> If 'this()' was used in the pointcut for binding, it must be passed first in proceed(..).
  54. * <li> If 'target()' was used in the pointcut for binding, it must be passed next in proceed(..) -
  55. * it will be the first argument to proceed(..) if this() was not used for binding.
  56. * <li> Finally come all the arguments expected at the join point, in the order they are supplied
  57. * at the join point. Effectively the advice signature is ignored - it doesn't matter
  58. * if a subset of arguments were bound or the ordering was changed in the advice signature,
  59. * the proceed(..) calls takes all of them in the right order for the join point.
  60. * </ul>
  61. * Since proceed(..) in this case takes an Object array, AspectJ cannot do as much
  62. * compile time checking as it can for code style. If the rules above aren't obeyed
  63. * then it will unfortunately manifest as a runtime error.
  64. *
  65. * @param args the arguments to proceed with
  66. * @return the result of proceeding
  67. * @throws Throwable if the invoked proceed throws anything
  68. */
  69. public Object proceed(Object[] args) throws Throwable;
  70. }

从源码上继承了JoinPoint

public Object proceed() throws Throwable;

Proceed with the next advice or target method invocation

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

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

Object getThis();

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

Object getTarget();

获取这个连接点上的参数

Object[] getArgs();

获取连接点上的签名。

Signature getSignature();

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AI编程探险家/article/detail/61407
推荐阅读
相关标签
  

闽ICP备14008679号