zoukankan      html  css  js  c++  java
  • SpringBoot博客开发之AOP日志处理

    日志处理:

    需求分析

    日志处理需要记录的是:

    1. 请求的URL
    2. 访问者IP
    3. 调用的方法
    4. 传入的参数
    5. 返回的内容

    上面的内容要求在控制台和日志中输出。

    在学习这部分知识的时候,真的感觉收获很多,在之前Spring学习的aop只是初步了解,现在有了一些深入的理解。好记性不如烂笔头!

    在日志处理这部分主要是aop的使用,通过切面的方式来整合到项目了,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

    人话:Aop 在不改变原有代码的情况下 , 去增加新的功能

    需要了解的:

    • 横切关注点:跨越应用程序多个模块的方法或功能。即是,与我们业务逻辑无关的,但是我们需要关注的部分,就是横切关注点。如日志 , 安全 , 缓存 , 事务等等 ....
    • 切面(ASPECT):横切关注点 被模块化 的特殊对象。即,它是一个类。
    • 通知(Advice):切面必须要完成的工作。即,它是类中的一个方法。
    • 切入点(PointCut):切面通知 执行的 “地点”的定义。
    • 连接点(JointPoint):与切入点匹配的执行点。

    通知(Advice)里面还有几种方法来帮助实现,这里我列举了该部分实现的方法:

    1. doBefore方法(方法前执行),需要注解@Before实现
    2. After方法(方法后执行),需要注解@After实现
    3. doAfterReturning方法,需要注解@AfterReturning实现

    具体实现看后面部分。

    重要部分:导入依赖

    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.9.4</version>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-aop</artifactId>
        <scope>test</scope>
    </dependency>
    

    提醒:导入包以后,刷新下Maven,如果运行的时候找不到包,重启试试,网上有很多的解决方法(也试过),最后个人只是重启一下子再刷新下maven就可以使用了。

    这里就没有给出解决方法,只是一个提醒。

    实现过程:

    创建一个类(LogAspect),将该类定义成一个切面(@Aspect)并且加入容器中(@Component)。

    首先创建一个切入点,后面的Advice是建立在切入点上:

    @Pointcut("execution(* com.blog.Controller..*.*(..))")
    public void log(){}
    

    整个表达式可以分为五个部分

    1、execution():表达式主体。
    2、第一个*号:表示返回类型,*号表示所有的类型。
    3、包名:表示需要拦截的包名,后面的两个句点分别表示当前包和当前包的所有子包,com.blog.Controller包、子孙包下所有类的方法。
    4、第二个*号:表示类名,*号表示所有的类。
    5、*(..) :第三个星号表示方法名,*号表示所有的方法,后面括弧里面表示方法的参数,两个句点表示任何参数

    定义完切入点后,处理前置通知和后置通知:

    @Before("log()")
    public void doBefore(JoinPoint joinPoint){
        System.out.println("在进入controller之前处理流-------------");
    }
    @After("log()")
    public void doAfter(){
        System.out.println("在进入controller之后处理流-------------");
    }
    //在切入点return内容之后切入内容(可以用来对处理返回值做一些加工处理)
    @AfterReturning(returning = "result",pointcut="log()")
    public void doAfterReturning(Object result){
        logger.info("Return ------ {}",result );
    }
    

    通过上述的简单介绍,可以知道我们如果需要知道需求里面的要求,我们的重点应该放到前置通知里面,在流处理之前获取前端操作的信息。

    核心代码如下:

    //通过上下文来获取请求里面的信息
    ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
    
    HttpServletRequest request = attributes.getRequest();
    //获取封装了署名信息的对象,在该对象中可以获取到目标方法名,所属类的Class等信息(反射)
    String classMethod = joinPoint.getSignature().getDeclaringTypeName()+","+joinPoint.getSignature().getName();
    // 1. 获取URL
    String url = request.getRequestURL().toString();
    //2. 获取ip地址
    String addr = request.getRemoteAddr();
    
    /*创建一个类RequestData,来保存相关信息*/
    RequestData requestData = new RequestData(
        url, addr, classMethod, joinPoint.getArgs()
    );
    //在控制台打印出来
    logger.info("RequestData------{}",requestData);
    

    创建的类是内部类(RequestData),只是封装一下需要打印的信息。

    实验效果:

    在进入controller之前处理流-------------
    2021-08-15 15:19:43.923  INFO 9644 --- [nio-8080-exec-1] com.blog.AspectAop.LogAspect             : RequestData------RequestData{url='http://localhost:8080/', ipAddr='0:0:0:0:0:0:0:1', classMethod='com.blog.Controller.IndexController,index', args=[]}
    2021-08-15 15:19:43.932  INFO 9644 --- [nio-8080-exec-1] com.blog.AspectAop.LogAspect             : Return ------ index
    在进入controller之后处理流-------------
    

    项目的github地址

    参考文献:

    狂神说Spring

    表达式参数

    结束:

    如果你看到这里或者正好对你有所帮助,希望能点个关注或者推荐,感谢;

    有错误的地方,欢迎在评论指出,作者看到会进行修改。

  • 相关阅读:
    Linux下VFP NEON浮点编译
    硬浮点 VFP
    程序员如何避免猝死?
    程序员谨防加班猝死之十大建议
    linux系统调用和库函数调用的区别
    彻底抛弃脚本录制,LR脚本之使用web_custom_request函数自定义
    LoadRunner监控mysql利器-SiteScope(转)
    linux mysql 数据库开启外部访问设置指南
    Java Web自定义MVC框架详解 (转)
    Jenkins+Ant+Jmeter搭建持续集成的接口测试平台(转)
  • 原文地址:https://www.cnblogs.com/xbhog/p/15208908.html
Copyright © 2011-2022 走看看