第一步:在pom.xml下添加依赖
- 因为springboot已经添加过日志记录功能的依赖
<!-- 核心模块,包括自动配置支持、日志支持 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0.4.0</version>
</dependency>
不但需要日志的依赖,还需要aop的依赖
第二步:在resources下新建logback.xml
- 将下面的代码贴入文件
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
<!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径,可以创建文件夹-->
<property name="LOG_HOME" value="D:/projects/log" />
<!-- 控制台输出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
</appender>
<!-- 按照每天生成日志文件 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--日志文件输出的文件名-->
<FileNamePattern>${LOG_HOME}/springbootdemo.log.%d{yyyy-MM-dd}.log</FileNamePattern>
<!--日志文件保留天数-->
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
<!--日志文件最大的大小-->
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>10MB</MaxFileSize>
</triggeringPolicy>
</appender>
<!--myibatis log configure,Myibatis的配置,会把他输出的语句输出出来-->
<logger name="com.apache.ibatis" level="DEBUG"/>
<logger name="java.sql.Connection" level="DEBUG"/>
<logger name="java.sql.Statement" level="DEBUG"/>
<logger name="java.sql.PreparedStatement" level="DEBUG"/>
<!-- 日志输出级别
trace<debug<info<warn<error<fatal
级别之间是包含的关系,意思是如果你设置日志级别是trace,则大于等于这个级别的日志都会输出。
trace: 是追踪,就是程序推进以下,你就可以写个trace输出,所以trace应该会特别多,不过没关系,我们可以设置最低日志级别不让他输出。
debug: 调试么,我一般就只用这个作为最低级别,trace压根不用。是在没办法就用eclipse或者idea的debug功能就好了么。
info: 输出一下你感兴趣的或者重要的信息,这个用的最多了。
warn: 有些信息不是错误信息,但是也要给程序员的一些提示,类似于eclipse中代码的验证不是有error 和warn(不算错误但是也请注意,比如以下depressed的方法)。
error: 错误信息。用的也比较多。
fatal: 级别比较高了。重大错误,这种级别你可以直接停止程序了,是不应该出现的错误么!不用那么紧张,其实就是一个程度的问题。
-->
<!--跟配置-->
<root level="DEBUG">
<appender-ref ref="STDOUT" />
<appender-ref ref="FILE" />
</root>
<!--日志异步到数据库,需要有日志表 -->
<!--<appender name="DB" class="ch.qos.logback.classic.db.DBAppender">-->
<!--<!–日志异步到数据库 –>-->
<!--<connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource">-->
<!--<!–连接池 –>-->
<!--<dataSource class="com.mchange.v2.c3p0.ComboPooledDataSource">-->
<!--<driverClass>com.mysql.jdbc.Driver</driverClass>-->
<!--<url>jdbc:mysql://127.0.0.1:3306/databaseName</url>-->
<!--<user>root</user>-->
<!--<password>root</password>-->
<!--</dataSource>-->
<!--</connectionSource>-->
<!--</appender>-->
</configuration>
第四步:新建一个LogUtil
- 日志记录有五种
- 前置通知
- 后置通知
- 异常通知
- 最终通知
- 环绕通知
- 下面是他们的实例。
- 知识点:
- 要想把一个类变成切面类,需要两步,
① 在类上使用 @Component 注解 把切面类加入到IOC容器中
② 在类上使用 @Aspect 注解 使之成为切面类
下面直接上完整代码,用@Aspect注解方式来实现前置通知、返回通知、后置通知、异常通知、环绕通知。
6. 注解不属于三层架构使用,@Component//交给spring管理
7. 通过映射可以拿到这个切面(service)的所有属性方法和
8. 切入点表达式@Pointcut(value = “execution(* com.aaa.sb.service..(…))”)
package com.aaa.sb.util;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
/**
* className:LogUtil
* discription:通知类(切面的实现类)
* author:luRuiHua
* createTime:2018-11-23 18:02
*/
//不属于三层架构
@Component//交给spring管理
@Aspect
public class LogUtil {
//切入点配置//切入点表达式
@Pointcut(value = "execution(* com.aaa.sb.service.*.*(..))")
public void pointCutOne() {};
/**
* 前置通知
*/
@Before(value = "pointCutOne()")//切入点指向切入点表达式
public void beforeSaveLog(JoinPoint joinPoint) {
//获取目标对象
String name = joinPoint.getTarget().getClass().getName();
System.out.println("再调用"+name+"的"+"调用:" + joinPoint.getSignature().getName() + "方法之前,打印。。。");
}
/**
* 后置通知
*/
@AfterReturning(value = "pointCutOne()")//切入点指向切入点表达式
public void afterReturningSavelog(JoinPoint joinPoint) {
//获取目标对象
String name = joinPoint.getTarget().getClass().getName();
System.out.println("再调用"+name+"的"+"调用:" + joinPoint.getSignature().getName() + "方法之前,打印。。。");
}
/**
* 异常通知
* 异常通知注解多了一个throwing = "exception"属性,值和参数列表中的值必须一样
* 模拟时需要在service制造异常
*/
@AfterThrowing(value = "pointCutOne()",throwing = "exception")//切入点指向切入点表达式
public void afterThrowingSavelog(JoinPoint joinPoint,Exception exception) {
//获取目标对象
String name = joinPoint.getTarget().getClass().getName();
System.out.println("再调用"+name+"的"+"调用:" + joinPoint.getSignature().getName() + "方法之前,打印。。。方法时出现了"+exception.getClass().getName()+"异常,异常描述为:"+exception.getMessage());
}
/**
* 最终通知
*/
@After(value = "pointCutOne()")//切入点指向切入点表达式
public void afterSavelog(JoinPoint joinPoint) {
//获取目标对象
String name = joinPoint.getTarget().getClass().getName();
System.out.println("再调用"+name+"的"+"调用:" + joinPoint.getSignature().getName() + "方法之后,无论有没有异常都会打印。。。");
}
/**
* 环绕通知
* 参数和其他通知不同
*/
@Around(value = "pointCutOne()")//切入点指向切入点表达式
public Object aroundSavelog(ProceedingJoinPoint proceedingJoinPoint) {
Object proceed = null;
System.out.println(System.currentTimeMillis()+"执行业务之前。。。。。。。。");
try {
proceed = proceedingJoinPoint.proceed();
} catch (Throwable throwable) {
throwable.printStackTrace();
}
System.out.println(System.currentTimeMillis()+"执行业务方法之后。。。。。。。");
return proceed;
}
}