目錄
1:pom.xml依賴
2:注解類樣例
3:枚舉類
4:具體處理方法類文章來源:http://www.zghlxwxcb.cn/news/detail-550131.html
5:線程池類文章來源地址http://www.zghlxwxcb.cn/news/detail-550131.html
1:pom.xml依賴
<!-- SpringBoot 攔截器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2:注解類樣例
package com.hgfr.gfs.logconfig.controller;
import java.lang.annotation.*;
/**
* 自定義操作日志記錄注解
*/
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface BusinessLog {
/**
* 操作人名稱
*/
public String OperationName() default "";
}
3:枚舉類
package com.hgfr.gfs.logconfig.controller;
public enum BusinessType {
ADD("新增"),
UPDATE("修改"),
OTHER("其他"),
EXPORT_IN("導(dǎo)入"),
EXPORT_OUT("導(dǎo)出"),
DELETE("刪除");
private String value;
BusinessType(String s) {
this.value =s;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
4:具體處理方法類
package com.hgfr.gfs.logconfig.controller;
import com.hgfr.gfs.log.entity.GsOperateLog;
import com.hgfr.gfs.log.service.IGsOperateLogService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.CodeSignature;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.TimerTask;
/**
* 注解解析
*/
@Aspect
@Component
@Slf4j
public class MyLogAspect {
//注解設(shè)置到類
@Pointcut("@annotation(com.hgfr.gfs.logconfig.controller.BusinessLog)")
public void logPointCut() {
}
@Autowired
IGsOperateLogService iGsOperateLogService;
/**
* 處理完請求前執(zhí)行
*
* @param joinPoint 切點(diǎn)
*/
@Before(value = "logPointCut()")
public void before(JoinPoint joinPoint) {
log.info("before");
}
/**
* 處理完請求后執(zhí)行
*
* @param joinPoint 切點(diǎn)
*/
@AfterReturning(pointcut = "logPointCut()", returning = "jsonResult")
public void doAfterReturning(JoinPoint joinPoint, Object jsonResult) {
log.info("doAfterReturning");
handleLog(joinPoint, null, jsonResult);
}
/**
* 攔截異常操作
*
* @param joinPoint 切點(diǎn)
* @param e 異常
*/
@AfterThrowing(value = "logPointCut()", throwing = "e")
public void doAfterThrowing(JoinPoint joinPoint, Exception e) {
log.info("doAfterThrowing");
handleLog(joinPoint, e, null);
}
protected void handleLog(final JoinPoint joinPoint, final Exception e, Object jsonResult) {
try {
// 獲得注解
BusinessLog controllerLog = getAnnotationLog(joinPoint);
if (Objects.isNull(controllerLog)) {
return;
}
// 數(shù)據(jù)庫日志
GsOperateLog sysOperationLog = new GsOperateLog();
// 處理設(shè)置注解上的參數(shù)
getControllerMethodDescription(joinPoint, controllerLog, sysOperationLog);
// 保存數(shù)據(jù)庫
// iGsOperateLogService.save(sysOperationLog);
ThreadPoolFactory.threadPoolExecutor.execute(saveTest(sysOperationLog));
} catch (Exception exp) {
// 記錄本地異常日志
log.error("==前置通知異常==");
log.error("異常信息:{}", exp.getMessage());
exp.printStackTrace();
}
}
public TimerTask saveTest(GsOperateLog sysOperationLog) {
return new TimerTask() {
@Override
public void run() {
// 耗時操作
try {
// 保存數(shù)據(jù)庫
iGsOperateLogService.save(sysOperationLog);
} catch (Exception e) {
log.error("SleepingTest:" + e.toString());
}
}
};
}
/**
* 獲取注解中對方法的描述信息 用于Controller層注解
*
* @param businessLog 日志
* @param sysOperationLog 操作日志
* @throws Exception
*/
public void getControllerMethodDescription(JoinPoint joinPoint, BusinessLog businessLog, GsOperateLog sysOperationLog) throws Exception {
sysOperationLog.setOperateType(businessLog.OperationType().getValue());
sysOperationLog.setRequestType(businessLog.OperationDetail());
String methodName = businessLog.MethodName();
sysOperationLog.setUserName(methodName);
}
/**
* 是否存在注解,如果存在就獲取
*/
private BusinessLog getAnnotationLog(JoinPoint joinPoint) throws Exception {
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
Method method = methodSignature.getMethod();
if (method != null) {
return method.getAnnotation(BusinessLog.class);
}
return null;
}
/**
* 獲取參數(shù)Map集合
* @param joinPoint
* @return
*/
Map<String, Object> getNameAndValue(JoinPoint joinPoint) {
Map<String, Object> param = new HashMap<>();
Object[] paramValues = joinPoint.getArgs();
String[] paramNames = ((CodeSignature) joinPoint.getSignature()).getParameterNames();
for (int i = 0; i < paramNames.length; i++) {
param.put(paramNames[i], paramValues[i]);
}
return param;
}
/**
* 處理完請求中執(zhí)行
* @param point 切點(diǎn)
*/
@Around("logPointCut()")
public Object around(ProceedingJoinPoint point) {
log.info("around");
//獲取方法名稱
Signature methodName = point.getSignature();
//日志輸出
log.info(methodName + "進(jìn)來了");
Long l1 = System.currentTimeMillis();
Object obj = null;
try {
obj = point.proceed(point.getArgs());
} catch (Throwable e) {
e.printStackTrace();
}
log.info(methodName + "bye" + "\t耗時 " + (System.currentTimeMillis() - l1));
//記錄一個耗時時間,將證明日志通知
return obj;
}
}
5:線程池類
package com.hgfr.gfs.logconfig.controller;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
@Slf4j
public class ThreadPoolFactory {
/**
* 線程池信息: 核心線程數(shù)量5,最大數(shù)量10,隊(duì)列大小20,超出核心線程數(shù)量的線程存活時間:30秒, 指定拒絕策略的
*/
public static final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5, 10, 30, TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(20), new RejectedExecutionHandler() {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
log.error("有任務(wù)被拒絕執(zhí)行了");
}
});
}
到了這里,關(guān)于java springboot架構(gòu) 自定義注解保存項(xiàng)目業(yè)務(wù)日志,使用線程池保存到數(shù)據(jù)庫的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!