使用AOP记录日志

@Aspect注解将表示它是一个切面

@Component表示它是一个Spring的组件

切片Aspect,既然Spring那么支持AOP,就肯定都能拿。有人会问如何拿原始的HTTP请求和响应的信息,通过以下代码应该拿得到啊哈哈哈哈

ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();

HttpServletRequest request = attributes.getRequest();

1
2
3
4
5
6
7
8
xml复制代码<aop:config>
<!-- order:指定切面bean的优先级,值越小,优先级越高 -->
<aop:aspect id="fourAdviceAspect" ref="fourAdviceBean" order="2">
<aop:around method="processTask" pointcut="execution(* com.wangjun.aop.xml.*.*(..))"/>
<aop:before method="authority" pointcut="execution(* com.wangjun.aop.xml.*.*(..))"/>
<aop:after-returning method="log" returning="rvt" pointcut="execution(* com.wangjun.aop.xml.*.*(..))"/>
</aop:aspect>
</aop:config>

其中aop:aspect/标签就是切面,此标签下面的aop:around/、aop:before/这些就是增强处理,那么在哪里进行增强处理呢?pointcut属性就定义了切入点,也就是在哪里进行增强处理。这里的表达式比如execution(* com.wangjun.aop.xml..(..))含义如下:

指定在com.wangjun.aop.xml包中任意类方法;

第一个表示返回值不限,第二个表示类名不限;

第三个*表示方法名不限,圆括号中的(..)表示任意个数、类型不限的形参。

使用场景

日志记录、审计、声明式事务、安全性和缓存等。

AspectJ和Spring AOP的区别

正好代表了实现AOP的两种方式:

AspectJ是静态实现AOP的,即在编译阶段对程序进行修改,需要特殊的编译器,具有较好的性能;

Spring AOP是动态实现AOP的,即在运行阶段动态生成AOP代理,纯java实现,因此无需特殊的编译器,但是通常性能较差。

案例:记录日志

业务日志表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
typescript复制代码package chin.common;

/**
* 操作类型枚举
*/
public enum OpearteType {
QUERY("检索","QUERY"),
CREATE("录入","CREATE"),
UPDATE("维护","UPDATE"),
DELETE("删除","DELETE"),
REVIEW("审核","REVIEW"),;

private String name;
private String code;

private OpearteType(String name, String code) {
this.name = name;
this.code = code;
}

public static String getName(String code) {
for (OpearteType c : OpearteType.values()) {
if (c.getCode().equals(code)) {
return c.name;
}
}
return null;
}

public static String getCode(String name) {
for (OpearteType c : OpearteType.values()) {
if (c.getName().equals(name)) {
return c.code;
}
}
return null;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getCode() {
return code;
}

public void setCode(String code) {
this.code = code;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
java复制代码package chin.annotation;

import chin.common.BusinessModule;

import java.lang.annotation.*;

/**
* 业务模块注解
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value = ElementType.TYPE)
public @interface BusinessModuleAttributes {
BusinessModule businessModule();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
java复制代码package chin.annotation;

import chin.common.OpearteType;

import java.lang.annotation.*;

/**
* 业务日志注解
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value = ElementType.METHOD)
public @interface BusinessLogAttributes {
OpearteType opearteType();
String opearteDescription();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
ini复制代码package chin.aspect;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.beyondbit.ias.core.base.BaseController;
import com.beyondbit.ias.core.util.IPUtil;
import chin.annotation.BusinessLogAttributes;
import chin.annotation.BusinessModuleAttributes;
import chin.entity.BusinessLog;
import chin.service.BusinessLogService;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.ui.Model;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.Date;

/**
* 业务日志切面
*/
@Aspect
@Component
public class BusinessLogAspect extends BaseController {

@Autowired
private BusinessLogService businessLogService;

@Pointcut("@annotation(chin.annotation.BusinessLogAttributes)")
public void logPointCut() {

}

@Around("logPointCut()")
public Object around(ProceedingJoinPoint point) throws Throwable {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();

BusinessModuleAttributes moduleAttributes = point.getTarget().getClass().getAnnotation(BusinessModuleAttributes.class);

MethodSignature signature = (MethodSignature) point.getSignature();
Method method = signature.getMethod();

BusinessLogAttributes logAttributes = method.getAnnotation(BusinessLogAttributes.class);

//获取请求参数:
MethodSignature ms = (MethodSignature) point.getSignature();
//获取请求参数类型
String[] parameterNames = ms.getParameterNames();
//获取请求参数值
Object[] parameterValues = point.getArgs();
StringBuilder strParams = new StringBuilder();
//组合请求参数,进行日志打印
if (parameterNames != null && parameterNames.length > 0) {
for (int i = 0; i < parameterNames.length; i++) {
if (parameterNames[i].equals("bindingResult")) {
break;
}
if ((parameterValues[i] instanceof HttpServletRequest) || (parameterValues[i] instanceof HttpServletResponse)||(parameterValues[i] instanceof Model)||(parameterValues[i] instanceof MultipartFile)) {
strParams.
append("[").
append(parameterNames[i]).append("=").append(parameterValues[i])
.append("]");
} else {
try
{
strParams.
append("[").
append(parameterNames[i]).append("=")
.append(JSON.toJSONString(parameterValues[i], SerializerFeature.WriteDateUseDateFormat))
.append("]");
}
catch(Throwable throwable){
strParams.
append("[").
append(parameterNames[i]).append("=").append(parameterValues[i])
.append("]");
}

}
}
}

Object result = null;
BusinessLog log = new BusinessLog();
log.setUuid(java.util.UUID.randomUUID().toString());
log.setClientIP(IPUtil.getClientIp(request));
log.setBusinessModule(moduleAttributes.businessModule().getCode());
log.setOpearteType(logAttributes.opearteType().getCode());
log.setOpearteDescription(logAttributes.opearteDescription());
log.setOpeartor(super.getCurrentUser().getUserUid());
log.setOpeartorName(super.getCurrentUser().getName());
log.setOpearteDateTime(new Date());
log.setReqUrl(request.getRequestURL().toString());
log.setClazz(point.getTarget().getClass().getName());
log.setMethod(method.getName());
log.setParams(strParams.toString());
try {
// 执行方法
result = point.proceed();
log.setStatus("1");
} catch (Exception e) {

log.setStatus("0");
log.setException(e.getStackTrace().toString());
throw e;
} finally {
businessLogService.insertBusinessLog(log);
}
return result;
}

}

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%