绵阳市淘金网络科技有限公司
首页 | 联系方式 | 加入收藏 | 设为首页 | 手机站

产品目录

联系方式

联系人:业务部
电话: 00143- 858031
邮箱:service@zmkuykj.com

当前位置:首页 >> 新闻中心 >> 正文

SpringBoot下用使用切面技术(AOP)配置日志

字号:
摘要:SpringBoot下用使用切面技术(AOP)配置日志

首先在pom.xml下导入aop的依赖

然后在resources文件夹底下配置log4j.properties文件

# LOG4J配置
log4j.rootCategory=INFO, stdout, file, errorfile //级别,控制台,文件,错误的日志
log4j.category.com.yy=DEBUG, bootfile //com.yy包底下所有产生的日志都会给它一个文件 my.log
log4j.logger.error=errorfile
# 控制台输出
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L - %m%n
# root日志输出
log4j.appender.file=org.apache.log4j.DailyRollingFileAppender //每天会产生一个日志文件
log4j.appender.file.file=logs/all.log
log4j.appender.file.DatePattern='.'yyyy-MM-dd //年月日的命名文件
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L - %m%n
# error下的日志输出
log4j.appender.errorfile=org.apache.log4j.DailyRollingFileAppender
log4j.appender.errorfile.file=logs/error.log
log4j.appender.errorfile.DatePattern='.'yyyy-MM-dd
log4j.appender.errorfile.Threshold = ERROR
log4j.appender.errorfile.layout=org.apache.log4j.PatternLayout
log4j.appender.errorfile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L - %m%n
# com.newer下的日志输出
log4j.appender.bootfile=org.apache.log4j.DailyRollingFileAppender
log4j.appender.bootfile.file=logs/my.log
log4j.appender.bootfile.DatePattern='.'yyyy-MM-dd
log4j.appender.bootfile.layout=org.apache.log4j.PatternLayout
log4j.appender.bootfile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L ---- %m%n

但是不知道怎么,这个log4j配置文件中的文件输出路径写的有问题(其实到后面我们做mongoDB就不用log4J来写了,而是logback来写,所以这里我就懒得弄了),所以我在application.yml里面重新配置下log文件输出的位置

然后就可以到controller层里面写切面了

package com.yy.hospital.controller;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
/**
 * web请求日志切面类---专门针对控制层,如谁被请求了,花了多少时间,请求发送的参数,返回得值等
 * @author yy
 */
@Aspect // 表示一个切面bean
@Component // bean容器的组件注解。虽然放在contrller包里,但它不是控制器。如果注入service,但我们又没有放在service包里
@Order(3) // 有多个日志时,ORDER可以定义切面的执行顺序(数字越大,前置越后执行,后置越前执行)
public class WebLogAspect {
 //定义日志记录器--获取sl4j包下提供的logger
 Logger logger = LoggerFactory.getLogger(this.getClass());
 ThreadLocal<Long> startTime = new ThreadLocal<>(); //线程副本类去记录各个线程的开始时间
 //定义切入点
 /*1、execution 表达式主体
 2、第1个* 表示返回值类型 *表示所有类型
 3、包名 com.*.*.controller下
 4、第4个* 类名,com.*.*.controller包下所有类
 5、第5个* 方法名,com.*.*.controller包下所有类所有方法
 6、(..) 表示方法参数,..表示任何参数
 */
 @Pointcut("execution(public * com.*.*.controller.*.*(..))")
 public void weblog() {
 }
 @Before("weblog()")
 public void dobefore(JoinPoint joinPoint) { //方法里面注入连接点
 logger.info("前置通知:"); //info ,debug ,warn ,erro四种级别,这里我们注入info级别
 startTime.set(System.currentTimeMillis());
 //获取servlet请求对象---因为这不是控制器,这里不能注入HttpServletRequest,但springMVC本身提供ServletRequestAttributes可以拿到
 ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
 HttpServletRequest request = attributes.getRequest();
 logger.info("URL:" + request.getRequestURL().toString()); // 想那个url发的请求
 logger.info("METHOD:" + request.getMethod());
 logger.info("CLASS_METHOD:" + joinPoint.getSignature().getDeclaringTypeName() + "."
 + joinPoint.getSignature().getName()); // 请求的是哪个类,哪种方法
 logger.info("ARGS:" + Arrays.toString(joinPoint.getArgs())); // 方法本传了哪些参数
 }
 //方法的返回值注入给ret
 @AfterReturning(returning = "ret", pointcut = "weblog()")
 public void doafter(Object ret) {
 logger.info("后置通知:");
 logger.info("RESPONSE:" + ret); // 响应的内容---方法的返回值responseEntity
 logger.info("SPEND:" + ( System.currentTimeMillis()-startTime.get() ));
 }
}