springaop+自定义注解实现日志记录

阿叮339      2022-04-03     797

关键词:

SpringAOP+自定义注解实现日志记录

 

关于自定义注解基本介绍可参考以往博客https://www.cnblogs.com/DFX339/p/11386722.html

此文主要是讲述如何通过注解标识记录日志信息,一般我们的Service接口都需要记录入参信息,参数校验,方法执行时间等

处理思路:

1.自定义注解,使用的时候通过加入注解即可注入相应的日志信息

2.使用SpringAOP, 识别注解标识的方法,切入日志信息

 

步骤一: 定义注解类 SystemLog.java 

package com.im.nexus.service.utils.logUtils;

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

/**
 * @description:系统日志注解(使用在Service类里面的方法上)
 * @author: duanfeixia
 * @time: 2020/5/12 10:54
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface SystemLog {
    String methoddesc() default "";//方法描述
}

 

步骤二:定义切面 SystemLogAspect.java

这里切记需要加入 @Component @Aspect 这两个注解,@Slf4j 这个注解是日志类的注解 非必选

package com.im.nexus.service.utils.logUtils;


import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
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.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * 自定义日志注解 SystemLog配合AOP注入日志信息
 */
@Component
@Aspect
@Slf4j
public class SystemLogAspect {

    // @SystemLog标识为切入点,切面会根据@SystemLog注解来注入数据
    @Pointcut("@annotation(com.imodule.nexus.service.utils.logUtils.SystemLog)")
    public void logPointCut(){
    }

    //环绕注入
    @Around("logPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        long startTime = System.currentTimeMillis();//记录目标方法的开始执行时间
        Object result = point.proceed();//执行目标方法
        long methodexecutetime = System.currentTimeMillis() - startTime;

        //日志信息记录
        try {
            MethodSignature methodSignature = (MethodSignature) point.getSignature();
            Method method = methodSignature.getMethod();
            SystemLog systemLog = method.getDeclaredAnnotation(SystemLog.class);
            String className = point.getTarget().getClass().getName();//类名
            String methodName = method.getName();//方法名

            //入参信息
            Object[] args = point.getArgs();
            List<String> list = new ArrayList<String>();
            for (Object obj : args) {
                    list.add(new Gson().toJson(obj));
            }
            log.info(className+"."+methodName+","+systemLog.methoddesc()+",入参:"+list.toString());
            log.info(className+"."+methodName+","+systemLog.methoddesc()+",耗时:"+methodexecutetime+"ms");
        } catch (Exception e) {
            log.error("日志切入出错");
        }
        return result;
    }
}

  

步骤三: 在具体Service实现类的方法上使用 @SystemLog注解

使用示例:@SystemLog(methoddesc = "方法说明内容")

package com.im.nexus.service.impl.prd;

import com.im.common.frame.exception.IMException;
import com.im.nexus.constant.NexusExceptionCodeEnum;
import com.im.nexus.dao.prd.PrdTsarateMapper;
import com.im.nexus.service.utils.BizParamCheckUtils;
import com.im.nexus.service.utils.ExceptionThrowUtils;
import com.im.nexus.service.utils.logUtils.SystemLog;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @description 产品接口实现类
 * @date 2020-03-31
 * @author duanfeixia
 */
@Service
@Slf4j
public class prdServiceImpl implements prdService {
    
    @Autowired
    private PrdTsarateMapper prdTsarateMapper;
    
    @Override
    @SystemLog(methoddesc = "是否简易核保-注解标识")
    public PrdResultDTO isSimple(String prdCode) throws IMException {
        //入參對象校驗
        BizParamCheckUtils.paramPropertyNullCheck("prdServiceImpl.getPrdStaticInfo:prdCode",prdCode);
        
    	PrdResultDTO prdResultDTO= new PrdResultDTO();
        try {
            Integer prdflag = prdTsarateMapper.isSimple(prdCode);
            /// 这里遵照了以前的写法,建议后续使用 1:是,0:否
            if (null != prdflag && prdflag > 0) {
                // 屬於簡易核保 : 0
            	prdResultDTO.setIsSimple(SysCnst.STR_FLAG_NO);
            } else {
                // 不屬於簡易核保 : 1
            	prdResultDTO.setIsSimple(SysCnst.STR_FLAG_YES);
            }
        } catch (Exception e) {
            log.error("prdServiceImpl.isSimple exception:[prdcode=" + prdCode + "]");
            ExceptionThrowUtils.logAndThrowException(NexusExceptionCodeEnum.EXCEPTION_DB_000001, e);
        }
        return prdResultDTO;
    }
}

  

步骤四:定义测试类,对以上方法进行测试(Junit单元测试)

package com.im.nexus.service.prd;

import com.im.common.frame.exception.IMException;
import com.im.nexus.DTO.prd.*;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;


@RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
public class prdServiceTest {

    @Autowired
    private prdService prdService;

    @Test
    public void testisSimple() throws IMException{
    	try {
            PrdResultDTO prdTsarateRtl = prdService.isSimple("12");
            log.info("是否简易核保:"+prdTsarateRtl);
            log.info("prdTsarateRtl.getIsSimple:"+prdTsarateRtl.getIsSimple());
		} catch (Exception e) {
			log.error("ceshi :", e);
		}
    }
}

 

执行单元测试后,测试结果如下:

[] 2020-05-12 12:59:33:331  INFO [main] c.i.n.s.u.logUtils.SystemLogAspect 51 - com.im.nexus.service.impl.prd.prdServiceImpl.isSimple,是否简易核保-PRD,入参:["12"]
[] 2020-05-12 12:59:33:331  INFO [main] c.i.n.s.u.logUtils.SystemLogAspect 52 - com.im.nexus.service.impl.prd.prdServiceImpl.isSimple,是否简易核保-PRD,耗时:66ms
[] 2020-05-12 12:59:33:331  INFO [main] c.i.n.service.prd.prdServiceTest 26 - 是否简易核保:PrdTsarateRtl{isSimple=1}
[] 2020-05-12 12:59:33:331  INFO [main] c.i.n.service.prd.prdServiceTest 27 - prdTsarateRtl.getIsSimple:1 

前面两行则是我们通过@SystemLog注解注入的日志内容

后面两行则是我们在Service实现类的方法中手写的日志内容

  

  

使用springaop自定义注解实现自动记录日志

百度加自己琢磨,以下亲测有效,所以写下来记录,也方便自己回顾浏览加深印象之类,有什么问题可以评论一起解决,不完整之处也请大佬指正,一起进步哈哈(1)首先配置文件:<!--声明自动为spring容器中配置@aspectj切面... 查看详情

springaop自定义注解实现日志管理

...认为是最灵活,可扩展的方式了,就拿日志管理来说,用SpringAOP自定义注解形式实现日志管理。废话不多说,直接开始!!!关于配置我还是的再说一遍。 在applicationContext-mvc.xml中要添加的    <mvc:annotation-dri... 查看详情

springboot中使用springaop实现日志记录功能

参考技术A一、创建日志注解1、日志类型枚举类2、自定义日志注解二、利用AOP实现日志切面统一处理1、日志实现类创建工厂2、切面类三、创建日志实现类1、添加日志接口2、添加日志接口实现类四、controller 查看详情

springboot—springaop实现系统操作日志记录存储到数据库

原文:https://www.jianshu.com/p/d0bbdf1974bd  采用方案:使用spring的aop技术切到自定义注解上,针对不同注解标志进行参数解析,记录日志缺点是要针对每个不同的注解标志进行分别取注解标志,获取参数进行日志记录输出1.需... 查看详情

springaop实现日志记录功能(代码片段)

...近项目中需要记录日志,跟大家想的一样,利用springaop去实现,之前也参考了一些代码,自己实现了一套设计,供大家参考。之前看到网上很多是基于切面类Aspect去实现了,在切面类中定义beforeafteraround等... 查看详情

自定义注解妙用,一行代码搞定用户操作日志记录,你学会了吗?(代码片段)

...点来获取到注解参数,然后将参数插入数据库记录2.SpringAOP对于SpringAop的基本介绍大家可以看看:https://blog.csdn.net/yjt520557/article/details/84833508这里是为了方便大家理解如何实现给大家解释一下2.1.关于SpringAOP的一些术语切面... 查看详情

自定义注解妙用,一行代码搞定用户操作日志记录,你学会了吗?(代码片段)

...点来获取到注解参数,然后将参数插入数据库记录2.SpringAOP对于SpringAop的基本介绍大家可以看看:https://blog.csdn.net/yjt520557/article/details/84833508这里是为了方便大家理解如何实现给大家解释一下2.1.关于SpringAOP的一些术语切面... 查看详情

自定义注解妙用,一行代码搞定用户操作日志记录,你学会了吗?(代码片段)

...点来获取到注解参数,然后将参数插入数据库记录2.SpringAOP这里是为了方便大家理解如何实现给大家解释一下2.1.关于SpringAOP的一些术语切面(Aspect):在SpringAOP中,切面可以使用通用类或者在普通类中以@Asp... 查看详情

自定义注解结合springaop实现权限,参数校验,日志等等功能(代码片段)

文章目录Aop(AspectOrientProgramming)使用场景实现一些共性需求:1.参数校验实现1.自定义注解参数,集合等等校验注解1.1FiledCheck字段校验注解1.2ListCheck集合校验注解1.3方法参数校验注解ModelCheck1.4参数校验注解2.定义Aop并且通... 查看详情

自定义日志注解+aop实现记录操作日志(代码片段)

...操作,但这样对业务代码入侵性太大,下面就结合AOP和自定义日志注解实现更方便的日志记录 首先看下一个简单的操作日志表 action_logidsubject(日志主题)content(日志内容)create_bycreate_time 日志主题可以用下面的枚... 查看详情

实现自定义springaop注解(代码片段)

实现自定义SpringAOP注解翻译原文链接ImplementingaCustomSpringAOPAnnotation1.介绍在本文中,我们将使用Spring中的AOP支持来实现自定义AOP注解。Inthisarticle,we’llimplementacustomAOPannotationusingtheAOPsupportinSpring.首先,我们将给出AOP的 查看详情

实现自定义springaop注解(代码片段)

实现自定义SpringAOP注解翻译原文链接ImplementingaCustomSpringAOPAnnotation1.介绍在本文中,我们将使用Spring中的AOP支持来实现自定义AOP注解。首先,我们将给出AOP的高级概述,解释它是什么及其优点。在此之后,我们将逐步实现我们的... 查看详情

jpom-aop+自定义注解实现操作日志记录

文章目录地址版本源码解析-AOP+自定义注解实现操作日志记录地址Gitee:https://gitee.com/dromara/Jpom官网:https://jpom.io/一款简而轻的低侵入式在线构建、自动部署、日常运维、项目监控软件。版本我们以2.8.12为例子,鉴赏学... 查看详情

springaop整合自定义注解做方法日志配置(源码在附件)

packagecom.aop.log.anno;importjava.lang.annotation.ElementType;importjava.lang.annotation.Retention;importjava.lang.annotation.RetentionPolicy;importjava.lang.annotation.Target;@Retention(RetentionPol 查看详情

springaop中@aspect拦截介绍(二)

...实现入参出参日志打印的小伙伴,要认真看那一大堆有关SpringAOP支持的AspectJ切入点指示符的注释了。使用@Pointcut("@within(com.example.springboot.common.aspectj.LogAspect)")就是在你想打日志的类上加上自定义注解@LogAspect;使用@Pointcut... 查看详情

springaop的自定义注解实践

   springaop属于spring的重要属性,在java中有相当广泛的用途,大家一般都接触过aop实现事务的管理,在xml里配好声明式事务,然后直接在service上直接加上相应注解即可,   今天我们来实现下SpringAOP的自定义注解,用... 查看详情

大聪明教你学java|springboot使用自定义注解实现操作日志的记录(代码片段)

...就比较麻烦了,而且容易出错误。这时候如果使用自定义注解的话就会方便很多,很大程度上简化了我们的代码,而且让代码可读性更强。👍那么今天就和大家分享一下如何利用自定义注解实现“记录操作日志”... 查看详情

使用aop以及自定义注解实现业务日志的收集(代码片段)

直接上代码自定义注解:MyLog@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public@interfaceMyLogStringvalue()default"";//value值是说明,会被记录到数据库里面自定义日志的实体类SysLog@Da 查看详情