通过线程池异步实现的目的是,尽量不去抢占主业务的资源,通过异步线程处理切面日志
@Configuration @EnableAsync public class ExecutorConfig { @Bean public Executor asyncServiceExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); //配置核心线程数 executor.setCorePoolSize(5); //配置最大线程数 executor.setMaxPoolSize(10); //配置队列大小 executor.setQueueCapacity(400); //配置线程池中的线程的名称前缀 executor.setThreadNamePrefix("thread-"); // rejection-policy:当pool已经达到max size的时候,如何处理新任务 // CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行 executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); //执行初始化 executor.initialize(); return executor; } }
其中,获取ip的工具类
public class IPUtils { private static Logger logger = LoggerFactory.getLogger(IPUtils.class); /** * 获取IP地址 * * 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址 * 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址 */ public static String getIpAddr(HttpServletRequest request) { String ip = null; try { ip = request.getHeader("x-forwarded-for"); if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("Proxy-Client-IP"); } if (StringUtils.isEmpty(ip) || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("WL-Proxy-Client-IP"); } if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("HTTP_CLIENT_IP"); } if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("HTTP_X_FORWARDED_FOR"); } if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } } catch (Exception e) { logger.error("IPUtils ERROR ", e); } // //使用代理,则获取第一个IP地址 // if(StringUtils.isEmpty(ip) && ip.length() > 15) { // if(ip.indexOf(",") > 0) { // ip = ip.substring(0, ip.indexOf(",")); // } // } return ip; } }实现类:@Async("asyncServiceExecutor")是关键
@Service("logService") public class LogServiceImpl implements LogService { private static Logger log = LoggerFactory.getLogger(LogServiceImpl.class); @Resource LogMapper logMapper; @Override @Async("asyncServiceExecutor") public void save(ProceedingJoinPoint joinPoint, long time, Object result, String userName, String ip, long begin) { try { MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Method method = signature.getMethod(); ApiOperation operation = method.getAnnotation(ApiOperation.class); //请求的方法名 String className = joinPoint.getTarget().getClass().getName(); String[] splitClassName = className.split("\\."); String methodName = splitClassName[splitClassName.length-1] + "." + signature.getName(); String operationStr = methodName; if (operation != null) { //注解上的描述 operationStr = operation.value(); } //请求的参数 Object[] args = joinPoint.getArgs(); String[] parameterNames = signature.getParameterNames(); JSONObject paramsJson = new JSONObject(); String params = ""; if (args != null && args.length > 0) { for (int i = 0; i < args.length; i++) { if (!BindingResult.class.isInstance(args[i])) { paramsJson.put(parameterNames[i], args[i]); } } params = paramsJson.toJSONString(); } if (StringUtils.isBlank(userName)) { if (args != null && args.length > 0) { if (UserEntity.class.isInstance(args[0])) { UserEntityuser = (UserEntity) args[0]; userName = user.getUserName(); } } } String startTime = DateUtils.format(DateUtils.getDate(begin, "yyyy-MM-dd HH:mm:ss"), "yyyy-MM-dd HH:mm:ss"); LogEntity sysLog = new LogEntity(userName, operationStr, methodName, params, startTime, time, JSONObject.toJSONString(result), ip); //保存系统日志 logMapper.save(sysLog); } catch (Exception e) { log.error("记录系统日志异常", e); } } }至于mapper的插入语句就不粘贴了,自己敲吧!