之前已经在项目里初步整合了log4j,SpringBoot2.1.0 + log4j 初步整合
本文主要分以下几个部分
- 实际应用角度log4j 和 整合 slf4j 后记录日志方式的区别
- 整合 slf4j 实际操作
- 引入lombok 使用 @Slf4j注解进一步简化日志记录
- MyEclipse 引入lombok后@Slf4j注解无效
- slf4j 以及 lombok 知识总结
一,首先从实际应用的角度来观察下加入SLF4J后,记录日志方式的细微区别
1,logger对象的获取
// log4j
private Logger logger = Logger.getLogger(getClass());
//slf4j
private Logger logger = LoggerFactory.getLogger(WebLogAspect.class);
2,传参日志的实现
但是log4j记录日志遇到需要传参时代码如下
logger.info("name:{" + name + "},value:{" + request.getParameter(name) + "}");
可以看出它增加了不必要的公式化的代码,减少了代码的可读性。所以为了简化日志参数传递,就引入了SLF4J,之后带参数的日志代码如下
logger.info("name:{},value:{}", name, request.getParameter(name));
可以很明显看出SLF4J提供了占位日志记录,提高了代码的可读性。
二,整合 slf4j 实际操作
首先是pom.xml
<!--log4j-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j</artifactId>
<version>1.3.8.RELEASE</version>
</dependency>
<!-- slf4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<!-- slf4j与log4j的关联jar包 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</dependency>
因为只是将对slf4j接口的调用转换为对log4j的调用,所以实质的log4j配置文件无需更改,之前的配置请看SpringBoot2.1.0 + log4j 初步整合
然后就直接到实际应用的地方了,这里依然用WebLogAspect举例(ps:注释的日志调用方式都是原始的log4j形式),代码如下
package com.soufun.aop;
import java.util.Enumeration;
import javax.servlet.http.HttpServletRequest;
import org.aspectj.lang.JoinPoint;
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.apache.log4j.Logger;
//import org.apache.log4j.spi.LoggerFactory;
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;
/*
* Author : baiye
Time : 2021/04/06
Function: 日志AOP
*/
@Component
@Aspect
public class WebLogAspect {
// private Logger logger = Logger.getLogger(getClass());
private Logger logger = LoggerFactory.getLogger(WebLogAspect.class);
@Pointcut("execution(public * com.soufun.controller..*.*(..))")
public void webLog() {
}
@Before("webLog()")
public void doBefore(JoinPoint joinPoint) throws Throwable {
//
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
//
// logger.info("URL : " + request.getRequestURL().toString());
// logger.info("HTTP_METHOD : " + request.getMethod());
// logger.info("IP : " + request.getRemoteAddr());
// slf4j.LoggerFactory
logger.info("URL : {}", request.getRequestURL().toString());
logger.info("HTTP_METHOD : {}", request.getMethod());
logger.info("IP : {}", request.getRemoteAddr());
Enumeration<String> enu = request.getParameterNames();
while (enu.hasMoreElements()) {
String name = enu.nextElement();
// logger.info("name:{" + name + "},value:{" + request.getParameter(name) +
// "}");
logger.info("name:{},value:{}", name, request.getParameter(name));
}
}
@AfterReturning(returning = "ret", pointcut = "webLog()")
public void doAfterReturning(Object ret) throws Throwable {
// logger.info("RESPONSE : " + ret);
logger.info("RESPONSE :{} ", ret);
}
}
运行测试之后控制台以及日志文件正常输出日志
三,引入lombok 使用 @Slf4j注解进一步简化日志记录
以上为止logger对象还是需要手动获取,那为了简化代码,这里选择引入lombok库,以@Slf4j注解方式来获取log对象。
还是pom.xml
<!--lombok简化代码-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
之后再看具体实现
package com.soufun.aop;
import java.util.Enumeration;
import javax.servlet.http.HttpServletRequest;
import org.aspectj.lang.JoinPoint;
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.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import lombok.extern.slf4j.Slf4j;
/*
* Author : baiye
Time : 2021/04/06
Function: 日志AOP
*/
@Component
@Aspect
@Slf4j
public class WebLogAspect {
// log4j
// private Logger logger = Logger.getLogger(getClass());
// slf4j.LoggerFactory
// private Logger logger = LoggerFactory.getLogger(WebLogAspect.class);
@Pointcut("execution(public * com.soufun.controller..*.*(..))")
public void webLog() {
}
@Before("webLog()")
public void doBefore(JoinPoint joinPoint) throws Throwable {
//
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
//
// logger.info("URL : " + request.getRequestURL().toString());
// logger.info("HTTP_METHOD : " + request.getMethod());
// logger.info("IP : " + request.getRemoteAddr());
// slf4j.LoggerFactory
// logger.info("URL : {}", request.getRequestURL().toString());
// logger.info("HTTP_METHOD : {}", request.getMethod());
// logger.info("IP : {}", request.getRemoteAddr());
log.info("URL : {}", request.getRequestURL().toString());
log.info("HTTP_METHOD : {}", request.getMethod());
log.info("IP : {}", request.getRemoteAddr());
Enumeration<String> enu = request.getParameterNames();
while (enu.hasMoreElements()) {
String name = enu.nextElement();
// logger.info("name:{" + name + "},value:{" + request.getParameter(name) +
// "}");
// logger.info("name:{},value:{}", name, request.getParameter(name));
log.info("name:{},value:{}", name, request.getParameter(name));
}
}
@AfterReturning(returning = "ret", pointcut = "webLog()")
public void doAfterReturning(Object ret) throws Throwable {
// logger.info("RESPONSE : " + ret);
// logger.info("RESPONSE :{} ", ret);
log.info("RESPONSE :{} ", ret);
}
}
这里可以看到只需要在使用log类前加上@Slf4j注解,就可以直接使用log来记录日志,省去了log对象的手动获取。
四,MyEclipse 引入lombok后@Slf4j注解无效
第一次引入lombok后加上@Slf4j发现注解无效,此时需要进行以下操作
找到导入的lombok的jar包,双击运行该jar包,会出现一个安装界面。
在安装界面选择当前的Eclipse进程,或者点击左下角的Specify location...选择要安装插件的myeclipse.exe,接着点右下角的Install / Update,之后点击Quit Installer。
安装完成就可以正常使用Lombok的系列注解了。
五,slf4j 以及 lombok 知识总结
slf4j
slf4j只是一个日志的标准框架,并不是日志系统的标准实现。它主要是
- 提供日志接口
- 提供获取日志对象的方法
所以以上只是借助slf4j稍微优化了以下log4j的实现,而且log4就并不能直接实现slf4j,所以还借助了slf4j-log4j12进行桥接来实现slf4j。
此外,其他的log4j2和logback也是类似,需要整合不同的包来实现,这里在网上看到了资料就也记录一下吧
1.slf4j与log4j整合导入的jar包为 :slf4j-api.jar slf4j-log4j12.jar log4j.jar
2.slf4j与log4j2整合导入的jar包为:slf4j-api.jar log4j-slf4j-impl.jar log4j-api.jar log4j-core.jar
3.slf4j与logback整合导入的jar包为:slf4j-api.jar logback-core.jar logback-classic.jar
lombok
提供了一些注解来简化java代码
官网:http://projectlombok.org/
查看lombok所有api:https://projectlombok.org/api/overview-summary.html
几个常用的 lombok 注解:
@Data:注解在类上;提供类所有属性的 getting 和 setting 方法,此外还提供了equals、canEqual、hashCode、toString 方法
@Setter:注解在属性上;为属性提供 setting 方法
@Getter:注解在属性上;为属性提供 getting 方法
@SneakyThrows:无需在签名处显式抛出异常
@Log4j:注解在类上;为类提供一个 属性名为log 的 log4j 日志对像
@Slf4j: 同上
@NoArgsConstructor:注解在类上;为类提供一个无参的构造方法
@AllArgsConstructor:注解在类上;为类提供一个全参的构造方法