java springboot架构 自定义注解保存项目业务日志,使用线程池保存到数据库

news/2024/10/24 4:38:10/

目录

1:pom.xml依赖

2:注解类样例

3:枚举类

4:具体处理方法类

5:线程池类


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("导入"),EXPORT_OUT("导出"),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 {//注解设置到类@Pointcut("@annotation(com.hgfr.gfs.logconfig.controller.BusinessLog)")public void logPointCut() {}@AutowiredIGsOperateLogService iGsOperateLogService;/*** 处理完请求前执行** @param joinPoint 切点*/@Before(value = "logPointCut()")public void before(JoinPoint joinPoint) {log.info("before");}/*** 处理完请求后执行** @param joinPoint 切点*/@AfterReturning(pointcut = "logPointCut()", returning = "jsonResult")public void doAfterReturning(JoinPoint joinPoint, Object jsonResult) {log.info("doAfterReturning");handleLog(joinPoint, null, jsonResult);}/*** 拦截异常操作** @param joinPoint 切点* @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;}// 数据库日志GsOperateLog sysOperationLog = new GsOperateLog();// 处理设置注解上的参数getControllerMethodDescription(joinPoint, controllerLog, sysOperationLog);// 保存数据库
//            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() {@Overridepublic void run() {// 耗时操作try {// 保存数据库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;}/*** 获取参数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;}/*** 处理完请求中执行* @param point 切点*/@Around("logPointCut()")public Object around(ProceedingJoinPoint point) {log.info("around");//获取方法名称Signature methodName = point.getSignature();//日志输出log.info(methodName + "进来了");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 {/*** 线程池信息: 核心线程数量5,最大数量10,队列大小20,超出核心线程数量的线程存活时间:30秒, 指定拒绝策略的*/public static final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5, 10, 30, TimeUnit.SECONDS,new LinkedBlockingQueue<Runnable>(20), new RejectedExecutionHandler() {@Overridepublic void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {log.error("有任务被拒绝执行了");}});}


http://www.ppmy.cn/news/904240.html

相关文章

jsp视频播放代码 avi

<video width"320" height"240" controls"controls"> <source src"love.mp4" type"video/mp4"> Your browser does not support the video tag. </video>

HTML网页上播放AVI视频代码示例

在 和 src中加入自己视频的地址. <!DOCTYPE HTML> <html><head><title> 测试视频播放</title><meta charset"utf-8"></head><body><object id"MediaPlayer" classid"clsid:22D6F312-B0F6-11D0-94…

【opencv的学习】播放avi视频和视频播放控制

播放硬盘中的视频文件 #include <cv.h> #include <highgui.h> #include<iostream> using namespace std;int main() {cvNamedWindow("Example2", CV_WINDOW_AUTOSIZE); //创建窗口CvCapture* capture cvCreateFileCapture("Example2.avi&…

前端网页/html播放mp4、avi、flv等视频,兼容ie7/7+ 调用flash/windows media player播放视频

废话不多说&#xff0c;先总结下亲测的几种方法&#xff1a; video标签法&#xff08;最常用&#xff0c;兼容现代浏览器、ie9/9&#xff1b;支持格式&#xff1a;MP4、ogg、webm&#xff09;flash&#xff08;兼容大多数浏览器、ie7/7&#xff0c;逐渐被淘汰&#xff0c;chro…

用VC++5.0播放AVI文件的两种方法

用Visual C开发的面向对象的多媒体应用软件可编译成 真正的EXE可执行文件,无需附加动态库和控件,如VBX和OCX 等。有两种方法可以实现这个功能,一种方法是使用底层AVI 文件函数,从AVI视频文件中读取视频流;另一种是使用现有的 Video forin dows SDK的窗口类MCIWnd(媒体控制界面窗…

网页嵌入WMP播放器播放avi视频

WMP是Windows Media Player的缩写。Windows Media Player 是 Windows 系统自带的播放器&#xff0c;可以播放MP3&#xff0c;WMA&#xff0c;WAV等音频文件&#xff0c;RM文件由于竞争关系微软默认并不支持&#xff0c;不过在V8以后的版本&#xff0c;如果安装了解码器&#xf…

Opencv入门(播放AVI视频)

Opencv入门(播放AVI视频) 需要注意如何循环地顺序读取视频中的每一帧&#xff0c;以及退出该循环操作&#xff0c;下面是一个简单的Opencv程序&#xff0c;用于播放硬盘中的视频文件 1. #include<highgui.h> 2. int main(int argc, char** argv) 3. { 4. cvNameWindow…

Python OpenCV第六课:播放AVI文件

OpenCV既可以读取连接电脑的摄像头视频&#xff0c;也可以读取本地视频文件。读取视频文件的第一步是要创建一个 VideoCapture 对象。它的参数可以是设备索引&#xff0c;也可以是要读取的视频文件名。在大多数情况下&#xff0c;只有一个摄像头连接到系统&#xff0c;所以传&q…