SpringBoot2.0 基础案例(11):配置AOP切面编程,解决日志记录业务

1本文源码 2GitHub地址:知了一笑 3https://github.com/cicadasmile/spring-boot-base

一、AOP切面编程

1、什么是AOP编程

在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP(面向对象编程)的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

2、AOP编程特点

11AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码 22)经典应用:事务管理、性能监视、安全检查、缓存 、日志等 33)aop底层将采用代理机制进行实现 44)接口 + 实现类 :spring采用 jdk 的动态代理Proxy 55)实现类:spring 采用 cglib字节码增强

3、AOP中术语和图解

11)target:目标类 2 需要被代理的类。例如:UserService 32)Joinpoint:连接点 4 所谓连接点是指那些可能被拦截到的方法。例如:所有的方法 53)PointCut:切入点 6 已经被增强的连接点。例如:addUser() 74)advice:通知/增强 8 增强代码。例如:after、before 95)Weaving:织入 10 指把增强advice应用到目标对象target来创建新的代理对象proxy的过程. 116)proxy 代理类 127) Aspect(切面): 是切入点pointcut和通知advice的结合 13 一个线是一个特殊的面。 14 一个切入点和一个通知,组成成一个特殊的面。

二、与SpringBoot2.0整合

1、核心依赖

1<!-- AOP依赖 --> 2<dependency> 3 <groupid>org.springframework.boot</groupid> 4 <artifactid>spring-boot-starter-aop</artifactid> 5</dependency>

2、编写日志记录注解

1package com.boot.aop.config; 2import java.lang.annotation.*; 3@Target(ElementType.METHOD) 4@Retention(RetentionPolicy.RUNTIME) 5@Documented 6public @interface LogFilter { 7 String value() default "" ; 8}

3、编写日志记录的切面代码

这里分为两种情况处理,一种正常的请求日志,和系统异常的错误日志。 核心注解两个。@Aspect和@Component。

1package com.boot.aop.config; 2import com.alibaba.fastjson.JSONObject; 3import org.aspectj.lang.ProceedingJoinPoint; 4import org.aspectj.lang.annotation.Around; 5import org.aspectj.lang.annotation.Aspect; 6import org.aspectj.lang.annotation.Pointcut; 7import org.aspectj.lang.reflect.MethodSignature; 8import org.slf4j.Logger; 9import org.slf4j.LoggerFactory; 10import org.springframework.stereotype.Component; 11import org.springframework.web.context.request.RequestContextHolder; 12import org.springframework.web.context.request.ServletRequestAttributes; 13import javax.servlet.http.HttpServletRequest; 14import java.lang.reflect.Method; 15 16@Aspect 17@Component 18public class LogAspect { 19 20 private static final Logger LOGGER = LoggerFactory.getLogger(LogAspect.class) ; 21 22 @Pointcut("@annotation(com.boot.aop.config.LogFilter)") 23 public void logPointCut (){ 24 25 } 26 @Around("logPointCut()") 27 public Object around (ProceedingJoinPoint point) throws Throwable { 28 Object result = null ; 29 try{ 30 // 执行方法 31 result = point.proceed(); 32 // 保存请求日志 33 saveRequestLog(point); 34 } catch (Exception e){ 35 // 保存异常日志 36 saveExceptionLog(point,e.getMessage()); 37 } 38 return result; 39 } 40 private void saveExceptionLog (ProceedingJoinPoint point,String exeMsg){ 41 LOGGER.info("捕获异常:"+exeMsg); 42 HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); 43 LOGGER.info("请求路径:"+request.getRequestURL()); 44 MethodSignature signature = (MethodSignature) point.getSignature(); 45 Method method = signature.getMethod(); 46 LOGGER.info("请求方法:"+method.getName()); 47 // 获取方法上LogFilter注解 48 LogFilter logFilter = method.getAnnotation(LogFilter.class); 49 String value = logFilter.value() ; 50 LOGGER.info("模块描述:"+value); 51 Object[] args = point.getArgs(); 52 LOGGER.info("请求参数:"+ JSONObject.toJSONString(args)); 53 } 54 private void saveRequestLog (ProceedingJoinPoint point){ 55 HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); 56 LOGGER.info("请求路径:"+request.getRequestURL()); 57 MethodSignature signature = (MethodSignature) point.getSignature(); 58 Method method = signature.getMethod(); 59 LOGGER.info("请求方法:"+method.getName()); 60 // 获取方法上LogFilter注解 61 LogFilter logFilter = method.getAnnotation(LogFilter.class); 62 String value = logFilter.value() ; 63 LOGGER.info("模块描述:"+value); 64 Object[] args = point.getArgs(); 65 LOGGER.info("请求参数:"+ JSONObject.toJSONString(args)); 66 } 67}

4、请求日志测试

1@LogFilter("保存请求日志") 2@RequestMapping("/saveRequestLog") 3public String saveRequestLog (@RequestParam("name") String name){ 4 return "success:"+name ; 5}

切面类信息打印

1/** 2 * 请求路径:http://localhost:8011/saveRequestLog 3 * 请求方法:saveRequestLog 4 * 模块描述:保存请求日志 5 * 请求参数:["cicada"] 6 */

5、异常日志测试

1@LogFilter("保存异常日志") 2@RequestMapping("/saveExceptionLog") 3public String saveExceptionLog (@RequestParam("name") String name){ 4 int error = 100 / 0 ; 5 System.out.println(error); 6 return "success:"+name ; 7}

切面类信息打印

1/** 2 * 捕获异常:/ by zero 3 * 请求路径:http://localhost:8011/saveExceptionLog 4 * 请求方法:saveExceptionLog 5 * 模块描述:保存异常日志 6 * 请求参数:["cicada"] 7 */

三、源代码地址

1GitHub地址:知了一笑 2https://github.com/cicadasmile/spring-boot-base 3码云地址:知了一笑 4https://gitee.com/cicadasmile/spring-boot-base

点赞
收藏

评论区

加载中...

相关推荐

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

推荐学java——Spring之AOP

tips:本文首发在公众号逆锋起笔,本文源代码在公众号回复aop即可查看。什么是AOP?AOP(AspectOrientProgramming),直译过来就是面向切面编程。AOP是一种编程思想,是面向对象编程(OOP)的一种补充。面向对象编程将程序抽象成各个层次的对象,而面向切面编程是将程序抽象成各个切面。为什么需要AOP?实际开发中我们应

SpringBoot Aop 详解和多种使用场景

前言aop面向切面编程,是编程中一个很重要的思想本篇文章主要介绍的是SpringBoot切面Aop的使用和案例什么是aopAOP(AspectOrientedProgramming):面向切面编程,面向切面编程(也叫面向方面编程),是目前软件开发中的一个热点,也是Spring框架中的一个重要内容。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻

Spring 学习笔记(四):Spring AOP

@\TOC\1概述本文主要讲述了AOP的基本概念以及在Spring中AOP的几种实现方式。2AOPAOP,即AspectOrientedProgramming,面向切面编程,与OOP相辅相成。类似的,在OOP中,以类为程序的基本单元,在AOP中的基本单元是Aspect

AOP相关概念

1.AOP(面向切面编程)在软件业,AOP为AspectOrientedProgramming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的延续,在软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生泛型.利用AOP

Spring框架中的AOP技术

1、AOP概述AOP技术即AspectOrientedProgramming的缩写,译为面向切面编程。AOP是OOP的一种延续,利用AOP技术可以对业务逻辑的各个部分进行隔离,从使得业务逻辑各部分之间的耦合性降低,提高程序的可重用性,同时提高了开发的效率。AOP采用横向抽取机制,取代了传统纵向继承体系重复性代码,AOP可以在不修改源代码的