[JAVA]spring-aop拦截controller以及service方法

  • 为了方便调试记录使用的参数,使用AOP将controller 以及service包下的方法做切面拦截所有的方法
package com.huifer.rpctest.aspect;

import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import javax.management.loading.PrivateClassLoader;
import lombok.Data;
import lombok.ToString;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import sun.security.krb5.internal.PAData;

@Component
@Aspect
public class ControllerAspect {

    @Pointcut("execution( * com.huifer.rpctest.controller.*.*(..) )")
    public void aspController() {

    }

    @Pointcut("execution( * com.huifer.rpctest.service.*.*(..) )")
    public void aspService() {

    }


    @AfterThrowing(pointcut = "aspController() || aspService()", throwing = "e")
    public void getControllerParam(JoinPoint joinPoint, Exception e) {

        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        // 当前被切点切到的方法
        Method method = signature.getMethod();
        // 参数名称
        String[] parameterNames = signature.getParameterNames();
        // 参数值
        Object[] args = joinPoint.getArgs();
        List<MethodAndArgs> methodAndArgsList = new ArrayList<>();
        if (parameterNames.length == args.length) {
            for (int i = 0; i < parameterNames.length; i++) {
                String parameterName = parameterNames[i];
                Object arg = args[i];
                MethodAndArgs methodAndArgs = new MethodAndArgs();
                methodAndArgs.setParameterName(parameterName);
                methodAndArgs.setArg(arg);
                methodAndArgsList.add(methodAndArgs);
            }
        }

        String className = joinPoint.getTarget().getClass().getName();
        String methodName = joinPoint.getSignature().getName();

        ControllerAop controllerAop = new ControllerAop();
        controllerAop.setClassName(className);
        controllerAop.setMethodName(methodName);
        controllerAop.setMethodAndArgs(methodAndArgsList);
        controllerAop.setTime(System.currentTimeMillis());
        controllerAop.setException(e);
        System.out.println(controllerAop);
    }

    @Data
    @ToString
    private static class MethodAndArgs {

        /**
         * 参数名称
         */
        private String parameterName;
        /**
         * 实际参数
         */
        private Object arg;
    }

    @Data
    @ToString
    private static class ControllerAop {

        /**
         * 类名
         */
        private String className;
        /**
         * 方法名
         */
        private String methodName;
        /**
         * 请求方法{参数名称:实际参数}
         */
        private List<MethodAndArgs> methodAndArgs = new ArrayList<>();

        private Exception exception;
        private long time;
    }

}


Java中,可以使用注解和AOP(面向切面编程)技术来拦截Controller的所有方法。 首先,需要创建一个自定义的注解,用于标识需要拦截方法。可以使用如下的注解定义: ```java import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Intercept { } ``` 接下来,创建一个切面类,用于实现拦截逻辑。可以使用如下的切面类定义: ```java import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component; @Aspect @Component public class ControllerInterceptor { @Pointcut("@annotation(Intercept)") public void interceptedMethods() {} @Before("interceptedMethods()") public void beforeIntercept() { // 在方法执行之前拦截的逻辑 } @After("interceptedMethods()") public void afterIntercept() { // 在方法执行之后拦截的逻辑 } } ``` 在上述的切面类中,使用了`@Aspect`注解表示这是一个切面类,使用了`@Component`注解将切面类交由Spring管理。`@Pointcut`注解定义了需要拦截方法,此处使用了`@annotation(Intercept)`表示拦截带有`Intercept`注解的方法。`@Before`和`@After`注解分别表示在方法执行前和执行后进行拦截处理。 最后,在需要拦截Controller方法使用`@Intercept`注解进行标记,例如: ```java @RestController public class MyController { @Intercept @GetMapping("/") public String index() { return "Hello World"; } } ``` 这样,只要在Controller方法使用了`@Intercept`注解,就会触发切面类中的拦截逻辑。 需要注意的是,上述代码使用Spring AOP来实现AOP功能,因此需要在Spring配置文件中开启AOP的支持。另外,还需要引入相关的依赖,例如Spring AOP的依赖。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值