SpringBoot通過AOP儲存操作日誌
阿新 • • 發佈:2019-01-11
專案中的一些重要操作需要記錄操作日誌,以便於以後操作出問題進行追蹤是誰操作引起的。
pom.xml引入AOP依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- aop -->
<dependency>
<groupId>org.springframework.boot</groupId >
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
在controller層新增攔截操作日誌
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SystemControllerLog {
String description() default "";
String type() default "b";
}
package com.rzg.dgztc.mall.manage.aop;
import com.rzg.dgztc.mall.manage.domain.PartnerLogisticsBean;
import com.rzg.dgztc.mall.manage.service.MallOptLogService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj .lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
@Aspect
@Component
public class SystemLogAspect {
private static final Logger log = LoggerFactory.getLogger(SystemLogAspect.class);
@Autowired
private MallOptLogService logService;
// controller層切點
@Pointcut("@annotation(com.rzg.dgztc.mall.manage.aop.SystemControllerLog)")
public void serviceAspect() {}
@Before("serviceAspect()")
public void doServiceBefore(JoinPoint joinPoint) {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
//請求的IP
String ip = request.getRemoteAddr();
//請求的引數
String param = getParam(joinPoint);
//請求的引數
String methodName = (joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()");
log.info("=====Service前置通知開始,方法:" + methodName + "=======");
log.info("請求方法:" + (joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()"));
log.info("方法型別:" + getServiceMthodType(joinPoint));
log.info("引數:" + param);
log.info("請求IP:" + ip);
log.info("=====Service前置通知結束=====");
log.info("url ={}",request.getRequestURI());
//日誌記錄到資料庫
logService.writeManageOptLog(ip, getServiceMthodType(joinPoint), methodName + param, request.getRequestURI());
}
/**
* 方法引數
* @param joinPoint
* @return
*/
private String getParam(JoinPoint joinPoint){
StringBuilder params = new StringBuilder();
if (joinPoint.getArgs() != null && joinPoint.getArgs().length > 0) {
for ( int i = 0; i < joinPoint.getArgs().length; i++) {
if(joinPoint.getArgs()[i].getClass() == PartnerLogisticsBean.class){
params.append(joinPoint.getArgs()[i].toString()).append(";");
}else{
params.append(joinPoint.getArgs()[i]).append(";");
}
}
}
return params.toString();
}
//操作型別,用於區分操作
private static String getServiceMthodType(JoinPoint joinPoint){
String targetName = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();
Object[] arguments = joinPoint.getArgs();
Class targetClass = null;
try {
targetClass = Class.forName(targetName);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
assert targetClass != null;
Method[] methods = targetClass.getMethods();
String type = "b";
for (Method method : methods) {
if (method.getName().equals(methodName)) {
Class[] clazzs = method.getParameterTypes();
if (clazzs.length == arguments.length) {
type = method.getAnnotation(SystemControllerLog.class).type();
break;
}
}
}
return type;
}
}
日誌儲存到資料庫
package com.rzg.dgztc.mall.manage.service;
import com.rzg.dgztc.mall.constant.ShiroConstants;
import com.rzg.dgztc.mall.entity.mall.MallOptLog;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
@Component
public class MallOptLogService {
/**
* 記錄系統日誌
*
* @param ip
* @param type
* @param logContent
*/
@Async
public void writeManageOptLog(String ip, String type, String logContent, String url) {
MallOptLog log = new MallOptLog();
log.setLog_content(logContent);
log.setOpt_type(type);
if (null != ShiroConstants.getCurrentUser()) {
log.setOpt_user(ShiroConstants.getCurrentUser().getId());
}
log.setUrl(url);
log.setOpt_time(ShiroConstants.currentTimeSecond());
log.setOpt_ip(ip);
log.insert();
}
}
最後在Controller層介面處新增
@SystemControllerLog(description = "下發分成", type = "d")
/**
* 下發分成
*
* @param orderId 訂單id
* @return
*/
@RequestMapping(value = "/grantDivide/{orderId}")
@ResponseBody
@SystemControllerLog(description = "下發分成", type = "d")
public String grantDivide(@PathVariable String orderId) {
}