springboot整合AOP实现日志操作

[图片上传失败...(image-f77bac-1717146408183)]

互相交流入口地址

整体目录:

【一】springboot整合swagger

【二】springboot整合自定义swagger

【三】springboot整合token

【四】springboot整合mybatis-plus

【五】springboot整合mybatis-plus

【六】springboot整合redis

【七】springboot整合AOP实现日志操作

【八】springboot整合定时任务

【九】springboot整合redis实现启动服务时热点数据保存在全局和缓存

【十】springboot整合quartz实现定时任务优化

【十一】springboot整合异步调用并获取返回值

【十二】springboot整合WebService

【十三】springboot整合WebService关于传参数

【十四】springboot整合WebSocket

【十五】springboot整合WebSocket实现聊天室

【十六】RabbitMQ基础篇(下载安装并基础使用,内含各种坑问题)

【十七】RabbitMQ基础篇(延迟队列和死信队列实战)

【十八】springboot实现自定义全局异常处理

【十九】初学Kafka并实战整合SpringCloudStream进行使用

【二十】springboot整合ElasticSearch实战(万字篇)

【二十一】springboot整合过滤器实战

【二十二】springboot整合拦截器实战并对比过滤器

【二十三】springboot整合activiti7(1)实战演示篇

【二十四】springboot整合spring事务详解以及实战

【二十五】springboot使用EasyExcel和线程池实现多线程导入Excel数据

【二十六】springboot整合jedis和redisson布隆过滤器处理缓存穿透

【二十七】springboot实现多线程事务处理

【二十八】springboot之threadLocal参数解析器实现session一样保存当前登录功能

【二十九】springboot整合logback实现日志管理

【三十】springboot项目上高并发解决示例

目录

第一步:新增日志实体类

第二步:新增各层代码

第三步:编写切面需要依赖的注解(次重点)

第四步:编写切面(重点)

第五步:演示


介绍:接下来我会把学习阶段学到的框架等知识点进行整合,每一次整合是在前一章的基础上进行的,所以后面的整合不会重复放前面的代码。每次的demo我放在结尾,本次是接着上一章的内容延续的,只增加新增的或者修改的代码。

上一章进行了Redis的整合,实现了一个用户对应一个token,用户登录失败次数锁定。

本章将整合AOP,实现请求接口后,对日志进行处理,不直接写到逻辑里面,尽量解耦,采用切面方式。

    首先展示下我的目录结构: 

[图片上传失败...(image-4b9291-1717146408183)]

    勾选部分为本章整合后新增部分代码。

第一步:新增日志实体类

@Data@TableName(value = "syslog")@Accessors(chain = true)public class SysLog {     private static final long serialVersionUID = 1L;     @TableId(type = IdType.UUID)    private String id;//id     @TableField("operationUser")    private String operationUser;//操作人     @TableField("path")    private String path;//请求路径     @TableField("time")    private String time;//方法执行时间     @TableField("parameter")    private String parameter;//方法入参     @TableField("title")    private String title;//操作方法     @TableField("action")    private String action;//方法描述     @TableField("sysType")    private Integer sysType;//系统类型     @TableField("opType")    private Integer opType;//操作类型     public SysLog(String operationUser, String path, String time,                      String parameter, String title, String action, Integer sysType, Integer opType) {        super();        this.operationUser = operationUser;        this.path = path;        this.time = time;        this.parameter = parameter;        this.title = title;        this.action = action;        this.sysType = sysType;        this.opType = opType;    } }

ps:此处所涉及的注解请不要漏写,关系到mybatis-plus的使用,此处id的自动设置不一定使用 IdType.UUID。

可以采用前面整合的代码生成器进行生成,我在此处就是使用代码生成器生成的,但是需要改进一些地方,不然会报错。

第二步:新增各层代码

[图片上传失败...(image-d289da-1717146408183)]

[图片上传失败...(image-34c1a8-1717146408183)]

[图片上传失败...(image-ab2883-1717146408183)]

第三步:编写切面需要依赖的注解(次重点)

[图片上传失败...(image-aa17c6-1717146408183)]

ps:自定义注解,需要加上框选部分的注解,里面参数的选择在csdn上面有大佬有细讲文章。

第四步:编写切面(重点)

@Aspect@Component@EnableAsyncpublic class SystemLogAspect {    @Resource    private SyslogMapper logMapper;//日志 mapper     private String requestPath = null ; // 请求地址    private long startTimeMillis = 0; // 开始时间    private long endTimeMillis = 0; // 结束时间    private String user = null; // 操作人    private HttpServletRequest request = null;//请求     /**     * 注解的位置     */    @Pointcut("@annotation(com.swagger.demo.config.OperationAnnotation)")    public void logPointCut() {}     /**     * @param joinPoint     * @Description 前置通知  方法调用前触发   记录开始时间,从session中获取操作人     */    @Before(value="logPointCut()")    public void before(JoinPoint joinPoint){        startTimeMillis = System.currentTimeMillis();    }    /**     * @param joinPoint     * @Description 获取入参方法参数     * @return     */    public Map<String, Object> getNameAndValue(JoinPoint joinPoint) {        Map<String, Object> param = new HashMap<>();        Object[] paramValues = joinPoint.getArgs();        String[] paramNames = ((CodeSignature)joinPoint.getSignature()).getParameterNames();        for (int i = 0; i < paramNames.length; i++) {            if(paramValues[i] instanceof Integer || paramValues[i] instanceof String) {                param.put(paramNames[i], paramValues[i]);            }        }        return param;    }    /**     * @param joinPoint     * @Description 后置通知    方法调用后触发   记录结束时间 ,操作人 ,入参等     */    @After(value="logPointCut()")    public void after(JoinPoint joinPoint) {        request = getHttpServletRequest();        String targetName = joinPoint.getTarget().getClass().getName();        String methodName = joinPoint.getSignature().getName();        Object[] arguments = joinPoint.getArgs();        Class<?> targetClass = null;        try {            targetClass = Class.forName(targetName);        } catch (ClassNotFoundException e) {            e.printStackTrace();        }        Method[] methods = targetClass.getMethods();        String title;        String action;        Integer sysType;        Integer opType;        Class<?>[] clazzs;        for (Method method : methods) {            if (method.getName().equals(methodName)) {                clazzs = method.getParameterTypes();                if (clazzs!=null&&clazzs.length == arguments.length                        &&method.getAnnotation(OperationAnnotation.class)!=null) {                    request = getHttpServletRequest();                    requestPath=request.getServletPath();                    HttpSession session = request.getSession();                    user = session.getAttribute("userName").toString();                    title = method.getAnnotation(OperationAnnotation.class).content();                    action = method.getAnnotation(OperationAnnotation.class).action();                    sysType = method.getAnnotation(OperationAnnotation.class).sysType();                    opType = method.getAnnotation(OperationAnnotation.class).opType();                    endTimeMillis = System.currentTimeMillis();                     SysLog log=new SysLog(user, requestPath,                            (endTimeMillis-startTimeMillis)+"ms",                            getNameAndValue(joinPoint).toString(), title, action,sysType,opType);                    System.out.println("增加参数:"+log);                    logMapper.insert(log);//                    break;                }            }        }    }    /**     * @Description: 获取request     */    public HttpServletRequest getHttpServletRequest(){        RequestAttributes ra = RequestContextHolder.getRequestAttributes();        ServletRequestAttributes sra = (ServletRequestAttributes)ra;        HttpServletRequest request = sra.getRequest();        return request;    }    /**     * @param joinPoint     * @return 环绕通知     * @throws Throwable     */    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {        return null;    }    /**     * @param joinPoint     * @Description 异常通知     */    public void throwing(JoinPoint joinPoint) {        System.out.println("异常通知");    }}

ps:下面对该切面进行一个解释。

[图片上传失败...(image-cecd12-1717146408183)]

    aspect注解表示将该类定义为切面。component注解表示将该类注册到spring容器。

[图片上传失败...(image-48b2d3-1717146408183)]

   pointcut注解表示定义切入点,此处表示,切入到 OperationAnnotation注解的位置,定义切入点的参数特别多,可以去细细了解一下。

[图片上传失败...(image-b4b338-1717146408183)]

    before注解表示前置通知,相当于BeforeAdvice的功能,value的值为切入点的名字。

[图片上传失败...(image-688434-1717146408183)]

    此方法是获取方法的入参。

[图片上传失败...(image-bfdcb4-1717146408183)]

    after注解表示后置通知,即使切入点注解切入位置执行完之后执行该部分代码。此处从session里面获取当前用户,表示日志的操作人(在登录时将用户名存入session),实际使用也可以采用其他办法。

[图片上传失败...(image-41b851-1717146408183)]

    使用mybatis-plus的insert方法直接新增的记录,也可以自己写sql。 
补充:改造了一下登录接口,登录成功后报错了用户名到session,如下。

[图片上传失败...(image-42522a-1717146408183)]

ps:使用session需要在入参处加上HttpServletRequest request。

[图片上传失败...(image-ac3afd-1717146408183)]

    从登录的controller方法到实现类都需要加上该入参。

第五步:演示

请求登录接口

[图片上传失败...(image-85a1df-1717146408183)]

    结果:

[图片上传失败...(image-d21120-1717146408183)]

    已经新增成功。

    本期整合到此完毕,接下来会继续更新加强整合,尽情期待。

    访问地址:[http://localhost:8088/swagger-ui.html](http://localhost:8082/swagger-ui.html "http://localhost:8088/swagger-ui.html")或者[http://localhost:8088/doc.html](http://localhost:8082/swagger-ui.html "http://localhost:8088/doc.html")

原文地址:https://blog.csdn.net/weixin_56995925/article/details/120160509

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容