【spring】使用spring的aop特性给接口加入参出参日志

package com.tencent.common.aoplog;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Created by developer on 2021/12/9.
 */
//只有定义为 RetentionPolicy.RUNTIME(在运行时有效)时,我们才能通过反射获取到注解,然后根据注解的一系列值,变更不同的操作。
@Target(ElementType.METHOD)
// 指定生效至运行时
@Retention(RetentionPolicy.RUNTIME)
public @interface AOPLog {
    /**
     * 指定是否详情显示
     * true 显示详情, 默认false
     *
     * @return
     */
    boolean isDetail() default false;

}

package com.tencent.common.aoplog;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
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.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

//指定切面类
@Aspect
// 注入容器
@Component
public class AOPLogAspect {

    private static Logger log = LoggerFactory.getLogger(AOPLogAspect.class);

    /**
     * 指定切点, 切点的位置是存在该注解com.tencent.common.aoplog.AOPLog
     */
    @Pointcut("@annotation(com.tencent.common.aoplog.AOPLog)")
    public void logPointCut() {
    }

    /**
     * 环绕通知, 该处写具体日志逻辑
     *
     * @param joinPoint
     */
    @Around("logPointCut()")
    public void logAround(ProceedingJoinPoint joinPoint) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        // 获取方法名称
        String methodName = signature.getName();
        // 获取入参
        Object[] param = joinPoint.getArgs();
        StringBuilder sb = new StringBuilder();
        for (Object o : param) {
            sb.append(o).append("; ");
        }
        log.info("进入方法[{}], 参数有[{}]", methodName, sb.toString());

        String resp = "";
        try {
            Object proceed = joinPoint.proceed();
            resp = JSON.toJSONString(proceed, SerializerFeature.WriteMapNullValue);
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }

        // 获取方法上的注解,判断如果isDetail值为true,则打印结束日志
        Method method = signature.getMethod();
        AOPLog annotation = method.getAnnotation(AOPLog.class);
        boolean isDetail = annotation.isDetail();
        if (isDetail) {
            log.info("执行结束[{}], 返回值[{}]", methodName, resp);
        }
    }

}
package com.tencent.pc.controller;

import com.tencent.common.aoplog.AOPLog;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author developer
 * @date 2019/12/26
 * @description //TODO
 */
@RestController
public class DemoController {

    // 指定注解@AOPLog
    @AOPLog(isDetail = true)
    @GetMapping("/demo0")
    public String demo0(String  name,String age) {
        return     "name"+name+"age"+age ;
    }

    // 指定注解@AOPLog, 同时isDetail = true
    //http://127.0.0.1:8080/demo1?name=xiaomi
    @AOPLog(isDetail = true)
    @GetMapping("/demo1")
    public String demo1(String  name) {
        return  "{ \"name\":\"xiaomi\" , \"age\":\"10\" },";
    }

}
2021-12-09 15:52:51.989  INFO 14140 --- [nio-8080-exec-3] com.tencent.common.aoplog.AOPLogAspect   : 进入方法[demo1], 参数有[xiaomi; ]
2021-12-09 15:52:51.989  INFO 14140 --- [nio-8080-exec-3] com.tencent.common.aoplog.AOPLogAspect   : 执行结束[demo1], 返回值["{ \"name\":\"xiaomi\" , \"age\":\"10\" },"]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring使用AOP(面向切面编程)是一种可以在运行时动态将横切关注点与程序主逻辑进行解耦的技术。在Spring中,AOP可以帮助我们实现诸如日志记录、事务管理、性能监控等与业务逻辑无关的功能。 要在Spring使用AOP,首先需要配置一个AOP代理,这个代理可以是基于Java动态代理(默认)或者CGLIB动态代理。然后,需要定义切点(Pointcut)来确定哪些方法将会被拦截。接下来,定义通知(Advice)来指定在方法执行前、后或异常抛出时应该执行的逻辑。最后,将切点和通知组合起来形成切面(Aspect),并将切面配置到Spring的配置文件中。 下面是一个简单的示例,展示了如何在Spring使用AOP: 1. 配置AOP代理方式: ```xml <bean id="myTarget" class="com.example.MyTarget" /> <aop:config> <aop:aspect id="myAspect" ref="myAspectBean"> <!-- 使用CGLIB动态代理 --> <aop:advisor advice-ref="myAdvice" pointcut="execution(* com.example.MyTarget.*(..))" /> </aop:aspect> </aop:config> ``` 2. 定义切面和通知: ```java public class MyAspect { public void beforeAdvice() { // 在方法执行前执行的逻辑 System.out.println("Before advice called."); } } public class MyAdvice implements MethodBeforeAdvice { @Override public void before(Method method, Object[] args, Object target) throws Throwable { // 在方法执行前执行的逻辑 System.out.println("Before advice called."); } } ``` 在上述示例中,我们配置了一个名为`myTarget`的目标对象,并定义了一个名为`myAspectBean`的切面。切面中使用了`myAdvice`这个通知,并通过`pointcut`指定了拦截`com.example.MyTarget`类中的所有方法。当这些方法被调用时,通知中的逻辑将会在方法执行前执行。 请注意,以上示例只是一个简单的演示,并且配置方式和细节可能因实际需求而有所不同。Spring提供了更多灵活和强大的AOP功能,包括不同类型的切点、多个通知的组合、异常处理等。你可以根据具体情况进行更详细的配置和调整。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值