大家好,我是二哥。AOP是Spring体系中两个非常重要的概念之一(另一个是IoC)。今天的文章将带大家通过实用的方法,在编程猫SpringBoot项目中,使用AOP技术为controller层添加切面。接口访问统一记录。1、关于AOPAOP,即Aspect-orientedProgramming,翻译为面向切面编程,是计算机科学中的一种设计思想,旨在通过切面技术为业务主体增加额外的建议(Advice),从而声明为“切点”(Pointcut)代码块进行统一管理和修饰。这种思路非常适用于在程序中加入与核心业务关系不是那么密切的功能,就像我们今天的话题——日志功能就是一个典型案例。AOP是面向对象编程(俗称OOP)的补充。OOP的核心单元是class,而AOP的核心单元是aspect。AOP可以用来隔离业务逻辑的各个部分,从而降低耦合,提高程序的复用性,提高开发效率。我们可以简单的把AOP理解为贯穿方法的操作,方法执行前、执行中、执行后、返回值后、异常后。2、AOP相关术语看下图,是一张AOP模型图,就是在某些方法执行前后进行一些常用的操作,而这些操作不会影响程序本身的运行。下面来了解一下AOP涉及的5个关键术语:1)横切关注点,每个方法中抽取出的同类型非核心业务2)Aspects,封装横切关注点的类,每个关注点表示为一个通知方法;通常一个方面是使用@Aspect注释定义的。3)建议(Advice),切面必须完成的具体任务。比如我们的日志方面需要记录接口调用前后的时间,那么我们就需要记录接口调用前后的时间,然后取差值。通知方法有五种:@Before:通知方法会在目标方法调用前执行@After:通知方法会在目标方法调用后执行@AfterReturning:通知方法会在目标方法返回后执行@AfterThrowing:通知方法会在目标方法抛出异常后Execute@Around之后执行:包装整个目标方法,在调用前后执行通知方法4)加入点(JoinPoint),通知的时机application,比如调用接口方法时,就是log切面的连接点。5)Pointcut,应用通知功能的范围。比如本文日志方面的应用范围是所有controller接口。切入点表达式通常使用@Pointcut注释定义。切入点表达式的语法格式规范如下:符号ret-type-pattern是返回类型,通常用*来表示任何返回类型declaring-type-pattern?是包名name-pattern是方法名,可以用*表示全部,也可以用set*表示全部以set开头param-pattern的类名)是参数类型,多个参数可以用,隔开participant也可以用*来表示所有类型的参数,(..)也可以用来表示零或任意参数throws-pattern?它是异常类型吗?表示前面一个是可选的例如:@Pointcut("execution(public*com.codingmore.controller.*.*(..))")表示com.codingmore.controller包下的所有publicmethods切面的Advice必须应用。3.实战AOP记录接口访问日志第一步是在SpringBoot项目的pom.xml文件中添加spring-boot-starter-aop依赖。org.springframework.bootspring-boot-starter-aop第二步添加日志信息封装类WebLog记录什么样的操作,谁在操作,开始时间,耗时,操作路径,操作方法名,操作主机IP,请求参数,返回结果等/***Controller层的日志封装类*2018年宏创建/4/26。*/publicclassWebLog{私有字符串描述;私有字符串用户名;私人长开始时间;私人整数花费时间;私人字符串基本路径;私有字符串uri私有字符串url;私有字符串方法;私有字符串ip;私有对象参数;私有对象结果;//省略getter和setter方法}第三步,添加统一的日志处理切面WebLogAspect。/***统一日志处理切面*Createdby石磊*/@Aspect@Component@Order(1)publicclassWebLogAspect{privatestaticfinalLoggerLOGGER=LoggerFactory.getLogger(WebLogAspect.class);@Pointcut("execution(public*com.codingmore.controller.*.*(..))")publicvoidwebLog(){}@Before("webLog()")publicvoiddoBefore(JoinPointjoinPoint)throwsThrowable{}@AfterReturning(value="webLog()",returning="ret")publicvoiddoAfterReturning(Objectret)throwsThrowable{}@Around("webLog()")publicObjectdoAround(ProceedingJoinPointjoinPoint)throwsThrowable{longstartTime=System.currentTimeMillis();//获取当请求请求对象ServletRequestAttributesattributes=(ServletRequestAttributes)RequestContextHolder.getRequestAttributes();HttpServletRequest请求=attributes.getRequest();//记录请求信息(通过Logstash传入Elasticsearch)WebLogwebLog=newWebLog();对象结果=joinPoint.proceed();签名signature=joinPoint.getSignature();MethodSignaturemethodSignature=(MethodSignature)签名;方法method=methodSignature.getMethod();if(method.isAnnotationPresent(ApiOperation.class)){ApiOperationlog=method.getAnnotation(ApiOperation.class);webLog.setDescription(log.value());}longendTime=System.currentTimeMillis();StringurlStr=request.getRequestURL().toString();webLog.setBasePath(StrUtil.removeSuffix(urlStr,URLUtil.url(urlStr).getPath()));webLog.setIp(request.getRemoteUser());MaplogMap=newHashMap<>();logMap.put("spendTime",webLog.getSpendTime());logMap.put("描述",webLog.getDescription());LOGGER.info("{}",JSONUtil.parse(webLog));返回结果;}}第四步,运行项目,勾选controller控制器下的某一项进行测试swaggerknife4j访问地址:http://localhost:9022/doc.html执行登录用户查询操作:在控制台可以看到如下日志信息:源码地址:https://github.com/itwanger/coding-more参考链接:作者cxuan:https://www.cnblogs.com/cxuanBlog/p/13060510.html灰小猿:https://bbs.huaweicloud.com/blogs/289045山是峰:https://万维网。cnblogs.com/liaojie970/p/7883687.htmlmacrozheng:https://github.com/macrozheng/mall本文转载自微信公众号“沉默王二”,可通过以下二维码关注。转载本文请联系沉默王二公众号。