AOP 实现日志

package com.foen.foensys.config;

import com.alibaba.fastjson.JSON;
import com.foen.foensys.model.SysLogsOper;
import com.foen.foensys.model.Users;
import com.foen.foensys.service.SysLogsOperService;
import com.foen.foensys.controller.admin.BaseController;
import com.foen.foensys.utils.DateUtils;
import com.foen.foensys.utils.Utils;
import com.google.common.collect.Maps;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
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.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.FileOutputStream;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;


/**
* AOP
* @auther: 作者 gzh
* @description: 类说明
* @Date: created in 15:33 2019/7/5
*/
@Order(value=1)//多个切面 ,第一个切面,
@Component
@Aspect
public class SystemLogsOperAopAction {

private static final Logger logger = LoggerFactory.getLogger(SystemLogsOperAopAction.class);

private long startTimeMillis = 0; // 开始时间
private long endTimeMillis = 0; // 结束时间
private long responseTime =0;
private String userId="-";
private String userName="-";
private String module;//执行模块
private String method;//执行方法
private String ip; //请求IP
private String remark; //执行备注
private String port;//端口
private String path;//操作路径
private String param;//参数
private Map<String, Object> outputParamMap = null; // 存放输出结果

@Autowired
private SysLogsOperService sysLogsOperService;

/**
* 00配置接入点:定义一个切入点
* execution(* com.foen.foensys.controller..*.*(..))") "*" 第一个* 任何返回值
*/
@Pointcut("execution(@com.foen.foensys.config.SystemLogs * *(..))")
private void controllerAspect(){
logger.info("==》 Controller Log SystemLogs 记录!");
}

/**
* 前置
* 1. 通过JoinPoint 获取通知的签名信息,如目标方法名,目标方法参数信息等
* @param joinPoint
*/
@Before(value = "controllerAspect() && @annotation(systemLogs)")
public void doAccessCheck(JoinPoint joinPoint,SystemLogs systemLogs){
startTimeMillis = System.currentTimeMillis();
logger.info("==>:前置通知,开始时间:"+ DateUtils.dateToStringDetail(new Date(startTimeMillis)));
}

/**
* 04. 后置最终通知(目标方法只要执行完了就会执行后置通知方法)
*/
@After("controllerAspect()")
public void after(JoinPoint joinPoint){
endTimeMillis = System.currentTimeMillis();
logger.info("==>:最终通知,时间"+DateUtils.dateToStringDetail(new Date(endTimeMillis)));
responseTime = endTimeMillis - startTimeMillis;
this.saveLog();
}




/**
* 环绕通知(之前前置,之后,后置通知,最终通知,整个生命周期都包括了)
* @param proceedingJoinPoint 目标对象
* @param systemLogs 自定义的注解,Around必须这样写,否则自定义的注解无法传入
* @return Object
* @throws Throwable
*/
@Around("controllerAspect() && @annotation(systemLogs)")
public Object around(ProceedingJoinPoint proceedingJoinPoint,SystemLogs systemLogs) throws Throwable {
/**
* 1.获取request信息
* 2.根据request获取session
* 3.从session中取出登录用户信息
*/
HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
Users user = (Users) request.getSession().getAttribute("user");
if(user!=null){
userId =""+user.getId();
if(StringUtils.isBlank(userId)){
userId="-";
}
userName = user.getUsername();
if(StringUtils.isBlank(userName)){
userName="-";
}
}
ip = request.getRemoteAddr();
port = Utils.getLocalPort();
path = request.getRequestURI();
param = request.getParameterMap().toString();
method = systemLogs.methods();
if(StringUtils.isBlank(method)){
method = "-";
}
module = systemLogs.module();
if(StringUtils.isBlank(module)){
module = "-";
}
outputParamMap = new HashMap<String,Object>();
param = getMyParam(request);


// 拦截的实体类,就是当前正在执行的controller
Object target = proceedingJoinPoint.getTarget();
// 拦截的方法名称。当前正在执行的方法
String methodName = proceedingJoinPoint.getSignature().getName();
// 拦截的方法参数
Object[] args = proceedingJoinPoint.getArgs();
// 拦截的放参数类型
Signature sig = proceedingJoinPoint.getSignature();
MethodSignature msig = null;
if (!(sig instanceof MethodSignature)) {
throw new IllegalArgumentException("该注解只能用于方法");
}
msig = (MethodSignature) sig;
Class[] parameterTypes = msig.getMethod().getParameterTypes();

Object object = null;
// 获得被拦截的方法
Method method = null;
try {
method = target.getClass().getMethod(methodName, parameterTypes);
} catch (NoSuchMethodException e1) {
e1.printStackTrace();
} catch (SecurityException e1) {
e1.printStackTrace();
}

// 判断是否包含自定义的注解,说明一下这里的SystemLog就是我自己自定义的注解
if (null != method) {
if (method.isAnnotationPresent(SystemLogs.class)) {
try {
object = proceedingJoinPoint.proceed();
remark="执行成功";
} catch (Throwable e) {
e.printStackTrace();
remark="执行异常";
}
} else {
logger.info("==>没有包含注解");
object = proceedingJoinPoint.proceed();
remark="没有包含注解";
}
} else {
logger.info("==>不需要拦截直接执行");
object = proceedingJoinPoint.proceed();
}
outputParamMap.put("result",object);
logger.info("==> 退出 环绕通知! object:"+object);
return object;
}

/**
* 取参数
* @param request
* @return String
*/
private String getMyParam(HttpServletRequest request) {
Map<?,?> inputParamMap = request.getParameterMap() ; // 传入参数
Enumeration<String> enumerations=request.getParameterNames();
Map<String,Object> parameterMaps= Maps.newHashMap();
while(enumerations.hasMoreElements()){
String parameter=enumerations.nextElement();
parameterMaps.put(parameter,request.getParameter(parameter));
}
return JSON.toJSONString(parameterMaps);
}


/**
*
* @param joinPoint
* @return
*/
private static String getRemark(JoinPoint joinPoint) {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
SystemLogs systemLogs = method
.getAnnotation(SystemLogs.class);
String remark = systemLogs.methods();
return remark;
}

/**
* 输出日志
*/
private void saveLog() {
SysLogsOper sysLogsOper = new SysLogsOper();
sysLogsOper.setIp(ip);
sysLogsOper.setPort(port);
sysLogsOper.setOperTime(DateUtils.dateToStringDetail(new Date()));
sysLogsOper.setPath(path);
sysLogsOper.setUserId(userId);
sysLogsOper.setUserName(userName);
sysLogsOper.setResponseTime(responseTime);
sysLogsOper.setParam(param);
sysLogsOper.setMethod(method);
sysLogsOper.setModule(module);
sysLogsOper.setRemark(remark);
sysLogsOperService.save(sysLogsOper);
}
}
posted @ 2019-11-08 17:24  A汉克先生  阅读(199)  评论(0编辑  收藏  举报