Spring对aop支持:Aspect切面注解用法

maven

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
    <version>2.1.6.RELEASE</version>
</dependency>
  • @Pointcut

定义一个切入点,我这里的切点是 controller 下的所有方法

@Pointcut("execution(public * com.nbyt.controller..*.*(..))")//切入点描述 这个是controller包的切入点
public void controllerLog(){}//签名,可以理解成这个切入点的一个名称

补充:Java路径通配符的写法

Ant 路径通配符支持 ?、*、** 注意通配符匹配不包括目录分隔符 /

“?”:匹配一个字符,如“config?.xml”将匹配“config1.xml”;

“*”:匹配零个或多个字符串,如“cn/*/config.xml”将匹配“cn/javass/config.xml”,但不匹配匹配“cn/config.xml”;而“cn/config-*.xml”将匹配“cn/config-dao.xml”;

“**”:匹配路径中的零个或多个目录,如“cn/**/config.xml”将匹配“cn/config.xml”,也匹配“cn/javass/spring/config.xml”;而“cn/javass/config-**.xml”将匹配“cn/javass/config-dao.xml”,即把“**”当做两个“*”处理。

参考:https://www.cnblogs.com/knowledgesea/p/11199350.html

  • @Before

切点之前执行

  • @After

切点之后执行

  • @Around

切点环绕执行

//执行切面方法,拿到返回值
Object result = joinPoint.proceed();
  • @AfterThrowing

捕获异常的类型为Exception,也可以指定异常进行捕获

@AfterThrowing(pointcut = "controllerLog() ", throwing = "ex")
public void doAfterThrowing(JoinPoint joinPoint, Exception ex) {
    String methodName = joinPoint.getSignature().getName();
    List<Object> args = Arrays.asList(joinPoint.getArgs());
    log.error("连接点方法为:" + methodName + ",参数为:" + args + ",异常为:" + ex);
}
案例:打印日志
@Aspect
@Component
@Slf4j
public class WebLogAspect {

    private final Logger logger = LoggerFactory.getLogger(WebLogAspect.class);

    @Pointcut("execution(public * com.nbyt.controller..*.*(..))")//切入点描述 这个是controller包的切入点
    public void controllerLog(){}//签名,可以理解成这个切入点的一个名称


    @Before("controllerLog()") //在切入点的方法run之前要干的
    public void logBeforeController(JoinPoint joinPoint) {

        InputMDC.putMDC();
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();//这个RequestContextHolder是Springmvc提供来获得请求的东西
        HttpServletRequest request = ((ServletRequestAttributes)requestAttributes).getRequest();

        // 记录下请求内容
        log.info("################  URL : " + request.getRequestURL().toString());
        log.info("################  请求方式 : " + request.getMethod());
        log.info("################  IP : " + request.getRemoteAddr());
        log.info("################  参数 : " + Arrays.toString(joinPoint.getArgs()));

        //下面这个getSignature().getDeclaringTypeName()是获取包+类名的   然后后面的joinPoint.getSignature.getName()获取了方法名
        log.info("################  方法 : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());

    }

    @AfterThrowing(pointcut = "controllerLog() ", throwing = "ex")
    public void doAfterThrowing(JoinPoint joinPoint, Exception ex) {
        InputMDC.putMDC();
        String methodName = joinPoint.getSignature().getName();
        List<Object> args = Arrays.asList(joinPoint.getArgs());
        log.error("连接点方法为:" + methodName + ",参数为:" + args + ",异常为:" + ex);

    }

    //记录方法参数,方法名,返回值的日志
    @Around("execution(public * com.nbyt.controller..*.*(..))")
    public Object sysExceptionCatchAndProcess(ProceedingJoinPoint joinPoint) throws Throwable {
        this.logBeforeProceed(joinPoint);
        Object result = joinPoint.proceed();
        this.logAfterProceed(joinPoint, result);
        return result;
    }

    private void logBeforeProceed(ProceedingJoinPoint joinPoint) {
        StringBuilder logBuilder = new StringBuilder();
        // 方法
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        logBuilder.append("==========方法参数日志。方法:");
        this.appendMethodPath(logBuilder, methodSignature);
        // 参数名,参数值
        String[] argNames = methodSignature.getParameterNames();
        Object[] args = joinPoint.getArgs();
        if (args != null && args.length > 0) {
            logBuilder.append("参数:");
        }
        Map<String,Object> map = new HashMap<>();
        for (int i = 0; i < argNames.length; i++) {
//            logBuilder.append(argNames[i]).append("=").append(JSONUtil.toJsonStr(args[i]));
            map.put(argNames[i],args[i]);
        }

        logBuilder.append(JSONUtil.toJsonStr(map));

//        logBuilder.append(Arrays.toString(argNames));
//        logBuilder.append(Arrays.toString(args));
        log.info(logBuilder.toString());

    }
    private void logAfterProceed(ProceedingJoinPoint joinPoint, Object result) {
        StringBuilder logBuilder = new StringBuilder();
        // 方法
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        logBuilder.append("==========方法返回日志。方法:");
        this.appendMethodPath(logBuilder, methodSignature);
        logBuilder.append("返回=").append(JSONUtil.toJsonStr(result));
        log.info(logBuilder.toString());
    }

    private void appendMethodPath(StringBuilder stringBuilder, MethodSignature methodSignature) {
        stringBuilder.append(methodSignature.getMethod().getDeclaringClass().toString())
                .append(".")
                .append(methodSignature.getMethod().getName())
                .append(" ");
    }
}
案例:统一入库
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值