上一篇介绍了springboot整合Mybatis例子,这一篇在上一篇的基础上,简单修改部分实现日志信息的打印。
随着项目功能的一点点增加,打印日志信息就非常必要了,可以帮助我们很快确定哪里出现了问题,这里使用slf4j来打印日志。
AOP即面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。如果几个或更多个逻辑过程中,有重复的操作行为,AOP就可以提取出来,运用动态代理,实现程序功能的统一维护,这样就非常方便了,在实现主业务过程中无需为一些零碎的但必不可少的旁支功能打扰,而是后期横切进去,这里接上一篇的代码来做,可以看出这个特点,对上一篇的代码没有做任何修改而成功打印出所需要的日志信息。关于AOP的更多知识,可以参考:理解Spring中的IOC和AOP。
接下来还是通过例子实现来看一看springboot如何使用AOP打印日志信息,接上一篇springboot学习(6)springboot整合Mybatis例子
首先,引入AOP的依赖包
<dependency> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
新建一个HttpAspect类,放在aspect包下:
package org.amuxia.aspect;import javax.servlet.http.HttpServletRequest;import org.aspectj.lang.annotation.AfterReturning;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.aspectj.lang.annotation.Pointcut;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.stereotype.Component;import org.springframework.web.context.request.RequestContextHolder;import org.springframework.web.context.request.ServletRequestAttributes;@Aspect@Componentpublic class HttpAspect { private Logger logger = LoggerFactory.getLogger(this.getClass()); @Pointcut("execution(public * org.amuxia.controller.ItemsController1.*(..))") public void myLog() { } @Before("myLog()") public void reqMessage() { ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); logger.info("*********打印请求信息开始**********"); logger.info("URL : " + request.getRequestURL().toString()); logger.info("HTTP_METHOD : " + request.getMethod()); logger.info("*********打印请求信息结束**********"); } @AfterReturning(returning="object",pointcut="myLog()") public void resMessage(Object object) { logger.info("*********打印结果信息开始**********"); logger.info("RESULT:"+ object); logger.info("*********打印结果信息结束**********"); } }
就这样,其余代码都不变,我们运行之后,输入http://localhost:8080/items1/list,控制台显示打印信息如下:
2017-12-24 16:59:41.070 INFO 6376 --- [nio-8080-exec-1] org.amuxia.aspect.HttpAspect : *********打印请求信息开始**********2017-12-24 16:59:41.070 INFO 6376 --- [nio-8080-exec-1] org.amuxia.aspect.HttpAspect : URL : http://localhost:8080/items1/list2017-12-24 16:59:41.070 INFO 6376 --- [nio-8080-exec-1] org.amuxia.aspect.HttpAspect : HTTP_METHOD : GET2017-12-24 16:59:41.070 INFO 6376 --- [nio-8080-exec-1] org.amuxia.aspect.HttpAspect : *********打印请求信息结束**********2017-12-24 16:59:41.373 INFO 6376 --- [nio-8080-exec-1] org.amuxia.aspect.HttpAspect : *********打印结果信息开始**********2017-12-24 16:59:41.373 INFO 6376 --- [nio-8080-exec-1] org.amuxia.aspect.HttpAspect : RESULT:ModelAndView: reference to view with name 'items'; model is {list=[Items [id=1, title=学习springboot, name=阿木侠, detail=说点儿什么呢], Items [id=2, title=我是一个标题, name=阿木侠, detail=我是内容,写点儿什么好呢], Items [id=3, title=我也是标题, name=阿木侠, detail=荷塘啊荷塘], Items [id=4, title=修改后的标题, name=amuxia, detail=修改后的内容], Items [id=6, title=这是新增的标题, name=阿木侠, detail=这是新增的内容], Items [id=13, title=花开花谢, name=花酒, detail=凄凄惨惨戚戚]]}2017-12-24 16:59:41.373 INFO 6376 --- [nio-8080-exec-1] org.amuxia.aspect.HttpAspect : *********打印结果信息结束**********
我们可以看到,已经成功将运行日志打印出来了。
代码不多,都非常容易理解,下面对上面用到的一些注解进行简单的介绍:
@Aspect 作用是把当前类标识为一个切面供容器读取。
@Before 标识一个前置增强方法,相当于BeforeAdvice的功能,从切入点开始处切入内容。
@AfterReturning 后置增强,相当于AfterReturningAdvice,方法正常退出时执行。
@Pointcut 定义一个切入点,可以是一个规则表达式,也可以是一个注解等。