一、背景
在公司写业务的时候,都会有保存日志的操作,方便出错的时候进行排查;一般不仅仅在数据库中保存日志,
也会在后端控制台打印一些需要的信息。在这里,一般使用 AOP 织入的方式将日志保存在数据库中,使用一些日
志包将某些 Controller 层的信息打印在控制台。
二、准备
Entiy:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| @Entity @Table(name = "log") @EntityListeners(AuditingEntityListener.class) public class Log implements Serializable {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY ) @Column(name = "id") private Long id;
@Column(name = "title", columnDefinition = "VARCHAR(100) COMMENT '标题'") private String title;
@Column(name = "author", columnDefinition = "VARCHAR(255) COMMENT '作者'") private String author;
@Column(name = "content", columnDefinition = "TEXT COMMENT '内容'") private String content;
|
注: 这里是使用 Spring Data JPA 自动生成的数据库对应实体,导入相关依赖后,可以先运行一遍,看数据库
是否生成对应实体;然后自行在数据库中插入几条数据。
Repository:
1 2 3
| public interface LogRepository extends JpaRepository<Log, Long> {
}
|
注: 这里只要继承 JpaRepository ,这个 repository 也继承了别的 repository(里面有一些常见的方法可以
调用)
Service:
1 2 3 4 5 6 7 8 9 10 11
| @Service public class LogService {
@Autowired LogRepository logRepository;
public List<Log> getAllLog() { List<Log> logs = logRepository.findAll(); return logs; } }
|
注: 这里就不写接口,再去实现了
Controller:
1 2 3 4 5 6 7 8 9 10 11 12
| @RestController public class LogController {
@Autowired LogService logService;
@GetMapping("/list") public List<Log> getAll() { List<Log> logs = logService.getAllLog(); return logs; } }
|
再使用 Postman 等工具进行一次测试就行
三、使用注解的方式进行 AOP
首先定义一个方法级别的 @Log 注解,用于标注需要监控的方法:
1 2 3 4 5 6 7
| @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface Log { String value() default ""; }
|
定义一个LogAspect类,使用 @Aspect 标注让其成为一个切面,切点为使用 @Log 注解标注的方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| @Aspect @Component public class LogAspec {
private final static Logger logger = LoggerFactory.getLogger(LogAspec.class);
@Pointcut("@annotation(org.wangba.springboot013aop.antoation.Log)") public void pointcut() { }
@Before("pointcut()") public void doBefore(JoinPoint joinPoint) throws Throwable { logger.info("Start Time: {}", System.currentTimeMillis()); }
@After("pointcut()") public void doAfter() throws Throwable { logger.info("End Time: {}", System.currentTimeMillis()); } }
|
再在 Controller 层的方法上加上 @Log 注解:
1 2 3 4 5 6 7 8 9 10 11 12 13
| @RestController public class LogController {
@Autowired LogService logService;
@Log("获得所有文章") @GetMapping("/list") public List<Article> getAll() { List<Article> articles = logService.getAllLog(); return articles; } }
|
此时再在 Postman 中测试一次,你就可以看到控制台会打印如下结果:

在公司业务中,我们一般都是在 @Before 进行一些请求信息等, @After 在控制台打印一些信息,并将结
果直接存到数据库中的日志表中。