使用AOP输出日志记录(自定义注解拦截Controller方法)

使用AOP输出日志记录(自定义注解拦截Controller方法)

1.自定义注解类

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface InterfaceSpLog {
    /*
     * 操作的页面(或模块)
     * */
    String operationName() default "";

    /*
     * 操作类型
     * */
    String operationType() default "";

    /**
     * 详细描述
     */
    String description() default "";
}

该注解用在Controller方法上面,operationName和operationType可以根据业务需求定义枚举类,没定义枚举类的话就赋值具体内容。使用示例:

@PostMapping("api/v1/...")
@ResponseBody
@InterfaceSpLog(operationName = "1",operationType = "1",description = "...")
public Object FunctionName(@RequestBody TDtSyszb tDtSyszb) {
    return xxService.xxFunction(tDtSyszb, false);
}

2.定义切面类

切面类用来处理日志内容。

前提知识讲解(个人粗鄙之见,有误请指正):
Controller方法:相当于切点(PointCut)
@Before前置通知:切点前的操作,通常只有登出操作为在before中记录日志
@Around环绕通知:供切入点使用,通常用来记录执行时间
@After后置通知:切点之后的操作,一般的用户操作都记录在这里,即controller方法执行完之后记录日志
@AfterReturning 可以获取到controller方法的返回值,方便有特殊业务要求的日志拼接

下面是示例代码,重点看@AfterReturning

@Aspect
@Component
@Slf4j
public class InterfaceSpLogAspect {

    //注入保存日志的工具类————这是我司封装好的工具类。
    //读者如果想把日志记录到数据库,可以注入相应的Mapper
    @Autowired
    private AuditLogUtil auditLogUtil;
    /*
     * 切点
     * */
    @Pointcut("@annotation(com.路径....InterfaceSpLog)")
    public void interfaceAspect(){
    }

    /**
    *Before
    */
    @Before("interfaceAspect()")
    public void doBefore(JoinPoint joinPoint){
    }

	//记录执行时间(没有也行)
    @Around("interfaceAspect()")
    public Object doAround(JoinPoint joinPoint){
        log.info("=================执行AOP环绕通知==================");
        long start = System.currentTimeMillis();
        Object obj = "";
        try {
            obj = ((ProceedingJoinPoint) joinPoint).proceed();
            long end = System.currentTimeMillis();
            if (logger.isInfoEnabled()) {
                logger.info("around " + joinPoint + "\tUse time : " + (end - start) + " ms!");
            }
            log.info("==============结束执行AOP环绕通知==================");
        } catch (Throwable e) {
            long end = System.currentTimeMillis();
            if (logger.isInfoEnabled()) {
                logger.error("around " + joinPoint + "\tUse time : " + (end - start) + " ms", e);
            }
        }
        return obj;
    }

    @AfterReturning(returning = "returnData",pointcut ="interfaceAspect()")
    public boolean doAfter(JoinPoint joinPoint,Object returnData) throws IllegalAccessException {
    	//从注解中获取到相关变量值
    	MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();
		//通过这几个变量判断当前是哪个模块在进行哪种操作(有需要的话,方法参数和返回值也可以参与判断)
        String operationName = method.getAnnotation(InterfaceSpLog.class).operationName();
        String operationType = method.getAnnotation(InterfaceSpLog.class).operationType();
        String description = method.getAnnotation(InterfaceSpLog.class).description();
        
        //通过反射获取当前被拦截的Controller方法的参数,returnData是当前方法的返回值,二者注意区分
        Object[] objects = joinPoint.getArgs();

		StringBuilder sb = new StringBuilder();  //sb用来拼接日志
		......//具体的拼接日志过程,如果有很多分类的话,可以使用Switch分情况,每种情况抽成一个方法,防止这个方法代码太臃肿
		
		......//最后,把拼接的日志插入到数据库
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值