Skip to content

Commit 9ea12a7

Browse files
authored
更新文档格式
1 parent d52ca16 commit 9ea12a7

File tree

1 file changed

+187
-189
lines changed

1 file changed

+187
-189
lines changed
Lines changed: 187 additions & 189 deletions
Original file line numberDiff line numberDiff line change
@@ -1,204 +1,202 @@
11
```text
22
在Spring框架中,使用AOP配合自定义注解可以方便的实现用户操作的监控。
33
1.引入mybatis依赖、mysql驱动依赖、druid数据源驱动依赖和aop依赖
4-
<dependency>
5-
<groupId>org.mybatis.spring.boot</groupId>
6-
<artifactId>mybatis-spring-boot-starter</artifactId>
7-
<version>1.3.2</version>
8-
</dependency>
9-
<dependency>
10-
<groupId>mysql</groupId>
11-
<artifactId>mysql-connector-java</artifactId>
12-
</dependency>
13-
<dependency>
14-
<groupId>com.alibaba</groupId>
15-
<artifactId>druid-spring-boot-starter</artifactId>
16-
<version>1.1.10</version>
17-
</dependency>
18-
<dependency>
19-
<groupId>org.springframework.boot</groupId>
20-
<artifactId>spring-boot-starter-aop</artifactId>
21-
</dependency>
4+
<dependency>
5+
<groupId>org.mybatis.spring.boot</groupId>
6+
<artifactId>mybatis-spring-boot-starter</artifactId>
7+
<version>1.3.2</version>
8+
</dependency>
9+
<dependency>
10+
<groupId>mysql</groupId>
11+
<artifactId>mysql-connector-java</artifactId>
12+
</dependency>
13+
<dependency>
14+
<groupId>com.alibaba</groupId>
15+
<artifactId>druid-spring-boot-starter</artifactId>
16+
<version>1.1.10</version>
17+
</dependency>
18+
<dependency>
19+
<groupId>org.springframework.boot</groupId>
20+
<artifactId>spring-boot-starter-aop</artifactId>
21+
</dependency>
2222
2.在application.yml文件中配置Druid数据源连接池及监控
23-
server:
24-
servlet:
25-
context-path: /web
26-
spring:
27-
datasource:
28-
druid:
29-
# 数据库访问配置, 使用druid数据源, 该MySQL驱动类名为新的
30-
driver-class-name: com.mysql.cj.jdbc.Driver
31-
# 设置URL时,如果是MySQL可能出现时区的问题,查看springboot设置时区
32-
url: jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8
33-
username: root
34-
password: root
35-
# 连接池配置
36-
initial-size: 5
37-
min-idle: 5
38-
max-active: 20
39-
# 连接等待超时时间
40-
max-wait: 30000
41-
# 配置检测可以关闭的空闲连接间隔时间
42-
time-between-eviction-runs-millis: 60000
43-
# 配置连接在池中的最小生存时间
44-
min-evictable-idle-time-millis: 300000
45-
validation-query: select '1' from dual
46-
test-while-idle: true
47-
test-on-borrow: false
48-
test-on-return: false
49-
# 打开PSCache,并且指定每个连接上PSCache的大小
50-
pool-prepared-statements: true
51-
max-open-prepared-statements: 20
52-
max-pool-prepared-statement-per-connection-size: 20
53-
# 配置监控统计拦截的filters, 去掉后监控界面sql无法统计, 'wall'用于防火墙
54-
filters: stat,wall
55-
# Spring监控AOP切入点,如x.y.z.service.*,配置多个英文逗号分隔
56-
aop-patterns: com.springboot.servie.*
57-
58-
# WebStatFilter配置
59-
web-stat-filter:
60-
enabled: true
61-
# 添加过滤规则
62-
url-pattern: /*
63-
# 忽略过滤的格式
64-
exclusions: '*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*'
65-
# StatViewServlet配置
66-
stat-view-servlet:
67-
enabled: true
68-
# 访问路径为/druid时,跳转到StatViewServlet
69-
url-pattern: /druid/*
70-
# 是否能够重置数据
71-
reset-enable: false
72-
# 需要账号密码才能访问控制台
73-
#login-username: admin
74-
#login-password: admin
75-
# IP白名单
76-
# allow: 127.0.0.1
77-
# IP黑名单(共同存在时,deny优先于allow)
78-
# deny: 192.168.1.218
79-
# 配置StatFilter
80-
filter:
81-
stat:
82-
log-slow-sql: true
83-
mybatis:
84-
# type-aliases扫描路径
85-
# type-aliases-package:
86-
# mapper xml实现扫描路径
87-
mapper-locations: classpath:mapper/*.xml
23+
server:
24+
servlet:
25+
context-path: /web
26+
spring:
27+
datasource:
28+
druid:
29+
# 数据库访问配置, 使用druid数据源, 该MySQL驱动类名为新的
30+
driver-class-name: com.mysql.cj.jdbc.Driver
31+
# 设置URL时,如果是MySQL可能出现时区的问题,查看springboot设置时区
32+
url: jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8
33+
username: root
34+
password: root
35+
# 连接池配置
36+
initial-size: 5
37+
min-idle: 5
38+
max-active: 20
39+
# 连接等待超时时间
40+
max-wait: 30000
41+
# 配置检测可以关闭的空闲连接间隔时间
42+
time-between-eviction-runs-millis: 60000
43+
# 配置连接在池中的最小生存时间
44+
min-evictable-idle-time-millis: 300000
45+
validation-query: select '1' from dual
46+
test-while-idle: true
47+
test-on-borrow: false
48+
test-on-return: false
49+
# 打开PSCache,并且指定每个连接上PSCache的大小
50+
pool-prepared-statements: true
51+
max-open-prepared-statements: 20
52+
max-pool-prepared-statement-per-connection-size: 20
53+
# 配置监控统计拦截的filters, 去掉后监控界面sql无法统计, 'wall'用于防火墙
54+
filters: stat,wall
55+
# Spring监控AOP切入点,如x.y.z.service.*,配置多个英文逗号分隔
56+
aop-patterns: com.springboot.servie.*
57+
# WebStatFilter配置
58+
web-stat-filter:
59+
enabled: true
60+
# 添加过滤规则
61+
url-pattern: /*
62+
# 忽略过滤的格式
63+
exclusions: '*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*'
64+
# StatViewServlet配置
65+
stat-view-servlet:
66+
enabled: true
67+
# 访问路径为/druid时,跳转到StatViewServlet
68+
url-pattern: /druid/*
69+
# 是否能够重置数据
70+
reset-enable: false
71+
# 需要账号密码才能访问控制台
72+
#login-username: admin
73+
#login-password: admin
74+
# IP白名单
75+
# allow: 127.0.0.1
76+
# IP黑名单(共同存在时,deny优先于allow)
77+
# deny: 192.168.1.218
78+
# 配置StatFilter
79+
filter:
80+
stat:
81+
log-slow-sql: true
82+
mybatis:
83+
# type-aliases扫描路径
84+
# type-aliases-package:
85+
# mapper xml实现扫描路径
86+
mapper-locations: classpath:mapper/*.xml
8887
3.自定义注解(标注要监控的方法)
89-
@Target(ElementType.METHOD)
90-
@Retention(RetentionPolicy.RUNTIME)
91-
public @interface Log {
92-
String value() default "";
93-
}
88+
@Target(ElementType.METHOD)
89+
@Retention(RetentionPolicy.RUNTIME)
90+
public @interface Log {
91+
String value() default "";
92+
}
9493
4.创建保存操作日志的库表:
95-
CREATE TABLE SYS_LOG (
96-
ID INTEGER(20) NOT NULL COMMENT 'ID',
97-
USERNAME VARCHAR(50) NULL COMMENT '用户名',
98-
OPERATION VARCHAR(50) NULL COMMENT '用户操作',
99-
TIME INTEGER(11) NULL COMMENT '响应时间',
100-
METHOD VARCHAR(200) NULL COMMENT '请求方法',
101-
PARAMS VARCHAR(500) NULL COMMENT '请求参数',
102-
IP VARCHAR(64) NULL COMMENT 'IP地址',
103-
CREATETIME DATE NULL COMMENT '创建时间'
104-
);
105-
ALTER TABLE SYS_LOG MODIFY ID INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY;
94+
CREATE TABLE SYS_LOG (
95+
ID INTEGER(20) NOT NULL COMMENT 'ID',
96+
USERNAME VARCHAR(50) NULL COMMENT '用户名',
97+
OPERATION VARCHAR(50) NULL COMMENT '用户操作',
98+
TIME INTEGER(11) NULL COMMENT '响应时间',
99+
METHOD VARCHAR(200) NULL COMMENT '请求方法',
100+
PARAMS VARCHAR(500) NULL COMMENT '请求参数',
101+
IP VARCHAR(64) NULL COMMENT 'IP地址',
102+
CREATETIME DATE NULL COMMENT '创建时间'
103+
);
104+
ALTER TABLE SYS_LOG MODIFY ID INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY;
106105
5.库表对应的实体JavaBean:
107-
public class SysLog implements Serializable{
108-
private static final long serialVersionUID = -6309732882044872298L;
109-
private Integer id;
110-
private String username;
111-
private String operation;
112-
private Integer time;
113-
private String method;
114-
private String params;
115-
private String ip;
116-
private Date createTime;
117-
// get,set略
118-
}
106+
public class SysLog implements Serializable{
107+
private static final long serialVersionUID = -6309732882044872298L;
108+
private Integer id;
109+
private String username;
110+
private String operation;
111+
private Integer time;
112+
private String method;
113+
private String params;
114+
private String ip;
115+
private Date createTime;
116+
// get,set略
117+
}
119118
6.编写Mapper接口:
120119
@Repository
121120
@Mapper
122-
public interface SysLogMapper {
123-
void saveSysLog(SysLog syslog);
124-
}
121+
public interface SysLogMapper {
122+
void saveSysLog(SysLog syslog);
123+
}
125124
7.编写Mapper的实现:
126-
<?xml version="1.0" encoding="UTF-8" ?>
127-
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
128-
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
129-
<mapper namespace="com.example.aoplog.dao.SysLogMapper">
130-
<insert id="saveSysLog" >
131-
insert into SYS_LOG(id,userName,operation,time,method,params,ip,createTime)
132-
values(#{id},#{userName},#{operation},#{time},#{method},#{params},#{ip},#{createTime})
133-
</insert>
134-
</mapper>
125+
<?xml version="1.0" encoding="UTF-8" ?>
126+
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
127+
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
128+
<mapper namespace="com.example.aoplog.dao.SysLogMapper">
129+
<insert id="saveSysLog" >
130+
insert into SYS_LOG(id,userName,operation,time,method,params,ip,createTime)
131+
values(#{id},#{userName},#{operation},#{time},#{method},#{params},#{ip},#{createTime})
132+
</insert>
133+
</mapper>
135134
8.编写切面类定义切点: (注意添加两个工具类:HttpContextUtils,IPUtils)
136-
@Aspect
137-
@Component
138-
public class LogAspect {
139-
@Autowired
140-
private SysLogMapper sysLogMapper;
141-
@Pointcut("@annotation(com.example.aoplog.annotation.Log)")
142-
public void poincut(){}
143-
@Around("poincut()")
144-
public Object around(ProceedingJoinPoint point){
145-
Object result =null;
146-
long start = System.currentTimeMillis();
147-
try {
148-
// 执行方法
149-
result = point.proceed();
150-
} catch (Throwable e) {
151-
e.printStackTrace();
152-
}
153-
long time = System.currentTimeMillis() - start;
154-
saveLog(point,time);
155-
return result;
156-
}
157-
private void saveLog(ProceedingJoinPoint point, long time) {
158-
MethodSignature signature = (MethodSignature) point.getSignature();
159-
Method method = signature.getMethod();
160-
SysLog sysLog = new SysLog();
161-
Log annotation = method.getAnnotation(Log.class);
162-
if (annotation != null){
163-
sysLog.setOperation(annotation.value());
164-
}
165-
String className = point.getTarget().getClass().getName();
166-
String methodName = signature.getName();
167-
sysLog.setMethod(className+"."+methodName);
168-
169-
Object[] args = point.getArgs();
170-
LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer();
171-
String[] paramNames = u.getParameterNames(method);
172-
if(args != null && paramNames != null){
173-
StringBuffer params = new StringBuffer();
174-
for (int i = 0; i < args.length; i++) {
175-
params.append(" "+paramNames[i]+": "+args[i]);
176-
}
177-
sysLog.setParams(params.toString());
178-
}
179-
HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
180-
sysLog.setIp(IPUtils.getIpAddr(request));
181-
sysLog.setUserName("admin");
182-
sysLog.setTime(time);
183-
sysLog.setCreateTime(new Date());
184-
sysLogMapper.saveSysLog(sysLog);
185-
}
186-
}
135+
@Aspect
136+
@Component
137+
public class LogAspect {
138+
@Autowired
139+
private SysLogMapper sysLogMapper;
140+
@Pointcut("@annotation(com.example.aoplog.annotation.Log)")
141+
public void poincut(){}
142+
@Around("poincut()")
143+
public Object around(ProceedingJoinPoint point){
144+
Object result =null;
145+
long start = System.currentTimeMillis();
146+
try {
147+
// 执行方法
148+
result = point.proceed();
149+
} catch (Throwable e) {
150+
e.printStackTrace();
151+
}
152+
long time = System.currentTimeMillis() - start;
153+
saveLog(point,time);
154+
return result;
155+
}
156+
private void saveLog(ProceedingJoinPoint point, long time) {
157+
MethodSignature signature = (MethodSignature) point.getSignature();
158+
Method method = signature.getMethod();
159+
SysLog sysLog = new SysLog();
160+
Log annotation = method.getAnnotation(Log.class);
161+
if (annotation != null){
162+
sysLog.setOperation(annotation.value());
163+
}
164+
String className = point.getTarget().getClass().getName();
165+
String methodName = signature.getName();
166+
sysLog.setMethod(className+"."+methodName);
167+
168+
Object[] args = point.getArgs();
169+
LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer();
170+
String[] paramNames = u.getParameterNames(method);
171+
if(args != null && paramNames != null){
172+
StringBuffer params = new StringBuffer();
173+
for (int i = 0; i < args.length; i++) {
174+
params.append(" "+paramNames[i]+": "+args[i]);
175+
}
176+
sysLog.setParams(params.toString());
177+
}
178+
HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
179+
sysLog.setIp(IPUtils.getIpAddr(request));
180+
sysLog.setUserName("admin");
181+
sysLog.setTime(time);
182+
sysLog.setCreateTime(new Date());
183+
sysLogMapper.saveSysLog(sysLog);
184+
}
185+
}
187186
9.编写Controller测试:
188-
@RestController
189-
public class TestController {
190-
@Log("查询的方法")
191-
@GetMapping("/query")
192-
public void query() throws InterruptedException { Thread.sleep(200); }
193-
194-
@Log("新增的方法")
195-
@PostMapping("/add")
196-
public void add(String name,int age,char sex) throws InterruptedException {
197-
Thread.sleep(500);
198-
}
199-
@Log("删除的方法")
200-
@DeleteMapping("/delete")
201-
public void delete(String name) throws InterruptedException { Thread.sleep(100); }
202-
}
187+
@RestController
188+
public class TestController {
189+
@Log("查询的方法")
190+
@GetMapping("/query")
191+
public void query() throws InterruptedException { Thread.sleep(200); }
192+
@Log("新增的方法")
193+
@PostMapping("/add")
194+
public void add(String name,int age,char sex) throws InterruptedException {
195+
Thread.sleep(500);
196+
}
197+
@Log("删除的方法")
198+
@DeleteMapping("/delete")
199+
public void delete(String name) throws InterruptedException { Thread.sleep(100); }
200+
}
203201
10.测试并查看数据库表: http://localhost:8080/web/XXX
204202
```

0 commit comments

Comments
 (0)