目录
AOP+单例模式+简单工厂模式实现操作日志记录
需求:对系统每一个接口的每一次访问,记录请求的操作日志,记录时间、ip、api名称、请求方式、url、参数等一些关键信息,并保存到数据库
画图分析
功能图解
类图
AOP--日志切面
/**
*日志切面类
*/
@Aspect
@Component
public class SysLogAspect {
@Autowired
SysLogService sysLogService;
@Autowired
SysLogDao sysLogDao;
private Long startTime;
private String ip;
private String interfaceName;
private String methodWays;
private String requestMethodUrl;
private String requestArgs;
//声明切点
@Pointcut("execution(public * com.gw.*.*.controller.*.*(..)) || execution(public * com.gw.*.controller.*.*(..))")
private void aspect() {
}
@Before("aspect()")
public void before(JoinPoint joinPoint) throws NoSuchMethodException {
//开始访问的时间
startTime = System.currentTimeMillis();
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = requestAttributes.getRequest();
//获取请求ip
ip = request.getRemoteAddr();
//获取请求方法名
interfaceName = request.getRequestURI();
//获取请求方式
methodWays = request.getMethod();
//获取请求方法地址
requestMethodUrl = joinPoint.getSignature().toString();
//获取请求参数
requestArgs = Arrays.toString(joinPoint.getArgs());
}
@AfterReturning(pointcut = "aspect()")
public void methodAfterReturning() {
Long endTime = System.currentTimeMillis();
//执行时长
Double time = (endTime - startTime) / 1000.0;
SysLog sysLog = new SysLog();
//获取当前用户
Subject currentUser = SecurityUtils.getSubject();
UserLoginInfo subject = (UserLoginInfo) currentUser.getPrincipal();
if (!ObjectUtils.isEmpty(subject)) {
//用户名
sysLog.setUserName(subject.getUserName());
}
//用户操作
switch (methodWays) {
case "GET":
// BusinessType为枚举类
sysLog.setOperation(BusinessType.SELECT.getValue());
break;
case "POST":
sysLog.setOperation(BusinessType.INSERT.getValue());
break;
case "PUT":
sysLog.setOperation(BusinessType.UPDATE.getValue());
break;
case "DELETE":
sysLog.setOperation(BusinessType.DELETE.getValue());
break;
}
//请求IP
sysLog.setIp(ip);
//请求类方法参数
sysLog.setParams(requestArgs);
//执行时长
sysLog.setTime(time.toString());
//请求方法路径
sysLog.setMethod(requestMethodUrl);
//入库时间
String createTime = DateTimeUtils.getNowDateTime();
sysLog.setCreateTime(createTime);
//获取系统接口路径信息列表
List<ApiInfo> apiInfos = sysLogDao.selectApiInfos();
for (ApiInfo apiInfo : apiInfos) {
//调用接口路径与接口信息列表进行匹配
if (apiInfo.getApiName().equals(interfaceName)) {
//菜单模块
sysLog.setMenuModel(apiInfo.getMenuOperation());
break;
}
}
//异步新增日志
AsyncManager.me().execute(AsyncFactory.recordOper(sysLog));
}
}
单例模式
/**
* 异步任务管理器
**/
public class AsyncManager {
/**
* 操作延迟10毫秒
*/
private final int OPERATE_DELAY_TIME = 10;
/**
* 异步操作任务调度线程池
*/
private ScheduledExecutorService executor = SpringUtils.getBean("scheduledExecutorService");
/**
* 单例模式
*/
private AsyncManager(){}
private static AsyncManager me = new AsyncManager();
public static AsyncManager me()
{
return me;
}
/**
* 执行任务
*
* @param task 任务
*/
public void execute(TimerTask task)
{
executor.schedule(task, OPERATE_DELAY_TIME, TimeUnit.MILLISECONDS);
}
/**
* 停止任务线程池
*/
public void shutdown()
{
ThreadsUtil.shutdownAndAwaitTermination(executor);
}
}
线程池
/**
* 执行周期性或定时任务
*/
@Bean(name = "scheduledExecutorService")
protected ScheduledExecutorService scheduledExecutorService()
{
return new ScheduledThreadPoolExecutor(corePoolSize,
new BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(true).build(),
new ThreadPoolExecutor.CallerRunsPolicy())
{
@Override
protected void afterExecute(Runnable r, Throwable t)
{
super.afterExecute(r, t);
ThreadsUtil.printException(r, t);
}
};
}
简单工厂模式
/**
*
**/
public class AsyncFactory {
/**
* 操作日志记录
*
* @param operLog 操作日志信息
* @return 任务task
*/
public static TimerTask recordOper(final SysLog operLog) {
return new TimerTask() {
@Override
public void run() {
// 远程查询操作地点
SpringUtils.getBean(SysLogService.class).addSysLogInfo(operLog);
}
};
}
}