1、创建springboot项目
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.4</version>
<classifier>jdk15</classifier>
</dependency>
</dependencies>
</project>
log4j.xml
# 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=D:/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=D:/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=D:/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
application.properties
server.port=8088
logging.level.*=debug
2、切面:
package com.example.demo.common.aspect;
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 {
//定义一个日志记录器
Logger logger=LoggerFactory.getLogger(this.getClass());
//定义一个线程本地变量,记录各个线程开始的时间
ThreadLocal<Long> starttime=new ThreadLocal<Long>();
/**
* 定义一个切入点
*/
@Pointcut("execution(public * com.*.*.controller.*.*(..))")
public void weblog(){
}
@Before("weblog()")
public void doBefore(JoinPoint joinPoint){
logger.info("前置通知");
starttime.set(System.currentTimeMillis());
//获取servlet请求对象---因为这不是控制器,这里不能注入HttpServletRequest,但springMVC本身提供ServletRequestAttributes可以拿到
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
logger.info("URL:"+request.getRequestURL().toString());
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()));
}
}
3、目标:
package com.example.demo.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class SampleController {
@RequestMapping("/home")
public String home() {
return "Hello World!";
}
}