需要大致了解:java日志基础,如核心组件Loggers,Appenders,Layouts的用处、SpringAOP概念
为什么需要日志
当应用程序部署到服务器上运行时,用户在使用过程中可能会出现各种错误。这时应用程序将错误信息生成日志,就方便了开发人员快速定位错误和根源,从而进行有针对的维护。所以,在大型应用程序中,日志记录是必不可少的。
选择日志框架
目前市面上可供选择的日志框架非常多,如JCL、SLF4J、Jboss-logging、jUL、log4j、log4j2、logback等,首先要分清楚 [日志抽象层] 和 [日志实现]。 这两者的关系可以参考设计模式中的“门面模式”。 我们在开发中调用日志记录方法时,不应直接调用日志实现类的方法,而是调用日志抽象层的方法。这样方便解耦,以后想更换别的日志实现时,可以直接改动配置文件的信息,而不用修改一行代码。 那么如何选择日志框架呢?
- 日志抽象层:JCL(Jakarta Commons Logging), SLF4j(Simple Logging Facade for Java), jboss-logging
- 日志实现:Log4j, JUL(java.util.logging), Log4j2, Logback
关于如何选择网络上有很多文章分析,在此不赘述。结论就是SLF4J更受开发者青睐,事实上《阿里java开发手册》上也规定:应用中不可直接使用日志系统(Log4j、Logback)中的API,而应依赖使用日志框架
SLF4J中的API,使用门面模式的日志框架,有利于维护和各个类的日志处理方式统一。
至于选择日志实现,log4j是很常用的,但其作者又写了log4j的升级版logback,相比log4j有更好的性能。有诸多理由让我们选择logback,使用好logback关键的一点就是配置好logback.xml文件,可参阅logback使用和配置详解
maven引入
1 | <dependency> |
SpringBoot已默认使用slf4j和logback 无需引入对应依赖。
如何插入日志记录
使用SpringAOP,目的是让开发者专注于业务逻辑而无需关心在哪里插入日志,并且可以降低日志记录操作对业务代码的侵入性。
这里我们使用 AspectJ 的几个注解来写一个切面类TestAspect.java
1 | import com.example.demo.annotation.RequestColor; |
以及Controller,有两个返回字符串的测试方法
1 | import com.example.demo.annotation.RequestColor; |
介绍几个常用的注解
- @Aspect 表明这个类是“切面类”,切面类就是用来定义切点和切点处要增强功能的方法
- @Pointcut 这个注解包含两部分,PointCut表达式和PointCut签名。表达式是用来确定切入点的位置的,说白了就是通过一些规则来确定,哪些方法是要增强的,也就是要拦截哪些方法。注解括号里的部分就是描述切点的位置,有很多种方法来确定,代码中使用的execution表达式是其中的一种,其语法和其他描述方法可自行百度。 签名就是被注解的方法名,签名没有实际用处,只是用来标记一个Pointcut,可以理解成这个切入点的一个记号。
- @Before 顾名思义,即在切入点处方法执行前,执行此方法。同下面的@After,@Around,@AfterReturning, @AfterThrowing注解类似,都是规定了在何时(相对于待增强方法)执行被注解的方法。只不过注解属性有所区别
- JoinPoint 代表着织入增强处理的连接点。注意一点:除了注解@Around的方法外,其他都可以加这个JoinPoint作参数,@Around注解的方法的参数一定要是ProceedingJoinPoint。 JoinPoint包含了几个很有用的参数:
- Object[] getArgs:返回目标方法的参数
- Signature getSignature:返回目标方法的签名
- Object getTarget:返回被织入增强处理的目标对象
- Object getThis:返回AOP框架为目标对象生成的代理对象
运行效果
理解了几个注解的作用后,通过运行结果,来看看测试方法都被哪些增强方法拦截了
启动后,在浏览器输入http://localhost:8080/ayahiro
可以看到,ayahiro()被所有增强方法拦截了。testControllerPointCut()和ayahiroPointCut()拦截不难理解,都前者是划定了一个范围,后者是直接具体定位到该方法。其中@After(value = “@annotation(requestColor)”) 的拦截方式比较特别,是通过自定义注解拦截的,因为ayahiro()被@RequestColor修饰,而@After拦截所有被@RequestColor修饰的方法。
输入http://localhost:8080/moonKa
可以看到@After就没有拦截moonKa方法,因为该方法没有被@RequestColor修饰。
使用日志
理解了AOP的思想之后,再结合slf4j记录日志就显得非常简单,调用日志方法只需要声明一个 private static final Logger logger = LoggerFactory.getLogger(当前类.class); 再用loger去调用具体的方法:.info() .warn() .debug() .error()即可~
参考资料: