目录

Life in Flow

知不知,尚矣;不知知,病矣。
不知不知,殆矣。

X

AOP 打印数据访问层摘要

APO 核心概念

APO 核心概念

Spring AOP 常用注解

  • @EnableAspectJAutoProxy:开启 AspectJ 的支持。
  • @Aspect:当前类是一个切面。(需要配合 @Component)
  • @Pointcut:
  • @Before:Advice 在 Join Point 之前执行。
  • @After :不管成功或失败,只要结束就会执行。
  • @AfterReturning :在成功 return 之后执行。
  • @AfterThrowing :在失败 return 之后执行。
  • @Around:环绕通知。前 + 后
  • @Order:用于指定切面的执行顺序。数值越小,优先级越高。

如何打印 SQL

HikariCP
 自身没有输出 SQL 的能力,需要借助 P6Spy。

1 <dependency>  
2 <groupId>p6spy</groupId>  
3 <artifactId>p6spy</artifactId>  
4 <version>3.8.1</version>  
5 </dependency>  

Alibaba Druid
 内置 SQL 输出
Druid 中使用 log4j2 进行日志输出

示例

引入依赖

 1<?xml version="1.0" encoding="UTF-8"?>
 2<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 3	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 4	<modelVersion>4.0.0</modelVersion>
 5	<parent>
 6		<groupId>org.springframework.boot</groupId>
 7		<artifactId>spring-boot-starter-parent</artifactId>
 8		<version>2.1.2.RELEASE</version>
 9		<relativePath/> <!-- lookup parent from repository -->
10	</parent>
11	<groupId>geektime.spring</groupId>
12	<artifactId>springbucks</artifactId>
13	<version>0.0.1-SNAPSHOT</version>
14	<name>springbucks</name>
15	<description>Demo project for Spring Boot</description>
16
17	<properties>
18		<java.version>1.8</java.version>
19	</properties>
20
21	<dependencies>
22		<dependency>
23			<groupId>org.springframework.boot</groupId>
24			<artifactId>spring-boot-starter-data-jpa</artifactId>
25		</dependency>
26
27		<dependency>
28			<groupId>org.joda</groupId>
29			<artifactId>joda-money</artifactId>
30			<version>1.0.1</version>
31		</dependency>
32		<dependency>
33			<groupId>org.jadira.usertype</groupId>
34			<artifactId>usertype.core</artifactId>
35			<version>6.0.1.GA</version>
36		</dependency>
37
38		<dependency>
39			<groupId>p6spy</groupId>
40			<artifactId>p6spy</artifactId>
41			<version>3.8.1</version>
42		</dependency>
43
44		<dependency>
45			<groupId>com.h2database</groupId>
46			<artifactId>h2</artifactId>
47			<scope>runtime</scope>
48		</dependency>
49		<dependency>
50			<groupId>org.projectlombok</groupId>
51			<artifactId>lombok</artifactId>
52			<optional>true</optional>
53		</dependency>
54		<dependency>
55			<groupId>org.springframework.boot</groupId>
56			<artifactId>spring-boot-starter-test</artifactId>
57			<scope>test</scope>
58		</dependency>
59	</dependencies>
60
61	<build>
62		<plugins>
63			<plugin>
64				<groupId>org.springframework.boot</groupId>
65				<artifactId>spring-boot-maven-plugin</artifactId>
66			</plugin>
67		</plugins>
68	</build>
69</project>

application.properties

1spring.datasource.driver-class-name=com.p6spy.engine.spy.P6SpyDriver
2spring.datasource.url=jdbc:p6spy:h2:mem:testdb
3spring.datasource.username=sa
4spring.datasource.password=
5
6spring.jpa.hibernate.ddl-auto=none
7#spring.jpa.properties.hibernate.show_sql=true
8#spring.jpa.properties.hibernate.format_sql=true

spy.properties
Reference

1# 单行日志
2logMessageFormat=com.p6spy.engine.spy.appender.SingleLineFormat
3# 使用Slf4J记录sql
4appender=com.p6spy.engine.spy.appender.Slf4JLogger
5# 是否开启慢SQL记录
6outagedetection=true
7# 慢SQL记录标准,单位秒
8outagedetectioninterval=2

PerformanceAspect

 1package geektime.spring.springbucks.aspect;
 2
 3import lombok.extern.slf4j.Slf4j;
 4import org.aspectj.lang.ProceedingJoinPoint;
 5import org.aspectj.lang.annotation.Around;
 6import org.aspectj.lang.annotation.Aspect;
 7import org.aspectj.lang.annotation.Pointcut;
 8import org.springframework.stereotype.Component;
 9
10@Aspect
11@Component
12@Slf4j
13public class PerformanceAspect {
14    /**
15     * 定义通知
16     * @param pjp
17     * @return
18     * @throws Throwable
19     */
20//    @Around("execution(* geektime.spring.springbucks.repository..*(..))")
21    @Around("repositoryOps()")
22    public Object logPerformance(ProceedingJoinPoint pjp) throws Throwable {
23        //执行方法前记录当前时间
24        long startTime = System.currentTimeMillis();
25        //打印目标方法的名字
26        String name = "-";
27        //执行失败就会变成 "N" ,默认是成功 "Y"
28        String result = "Y";
29        try {
30            //获取目标方法的名字
31            name = pjp.getSignature().toShortString();
32            //执行目标方法
33            return pjp.proceed();
34        } catch (Throwable t) {
35            result = "N";
36            throw t;
37        } finally {
38            //在方法执行之后 记录当前时间
39            long endTime = System.currentTimeMillis();
40            //记录方法的耗时
41            log.info("{};{};{}ms", name, result, endTime - startTime);
42        }
43    }
44
45    /**
46     * 定义 切入点
47     * 拦截 geektime.spring.springbucks.repository 包下面所有类的所有方法
48     * 这里是拦截 repository 层
49     * 如果想要拦截 service 层 可以如法炮制。
50     */
51    @Pointcut("execution(* geektime.spring.springbucks.repository..*(..))")
52    private void repositoryOps() {
53    }
54}

控制台输出

12020-01-15 18:27:01.555  INFO 6504 --- [           main] g.s.s.aspect.PerformanceAspect           : CrudRepository.save(..);Y;11ms

作者:Soulboy