import java.lang.reflect.Modifier; import javassist.ClassClassPath; import javassist.ClassPool; import javassist.CtClass; import javassist.CtMethod; import javassist.bytecode.CodeAttribute; import javassist.bytecode.LocalVariableAttribute; import javassist.bytecode.MethodInfo; import org.apache.commons.lang.ArrayUtils; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.alibaba.fastjson.JSON; /**@Description 哪个资方需要输出日志,自己到**-config工程下的spring-commons.xml配置 <!-- 日志打印 --> <bean id="aopLog" class="com.XXXXXXX.AopLog"/> * @author : 陈惟鲜 danger * @Date : 2018年8月9日 下午5:59:55 * */ @Aspect public class AopLog { private Logger logger = LoggerFactory.getLogger(getClass()); /**拦截所有controller包下的方法*/ @Pointcut("execution(* com.sinaif.king..controller..*.*(..))") private void controllerMethod(){}//定义一个切入点 /**拦截所有service包下的方法*/ @Pointcut("execution(* com.sinaif.king..service..*.*(..))") private void serviceMethod(){}//定义一个切入点 // // 1、前置通知: 在目标方法开始之前执行(就是要告诉该方法要在哪个类哪个方法前执行) // @Before("controllerMethod() || serviceMethod()") // public void beforeMethod(JoinPoint joinPoint) { // String methodName = joinPoint.getSignature().getName(); // String className = joinPoint.getTarget().getClass().getName(); // String msgInfo = "【" + className + "." + methodName + "】"; // logger.info(msgInfo + "......start.........."); // } // // // 2、后置通知:在目标方法执行后(无论是否发生异常),执行的通知 // // 注意,在后置通知中还不能访问目标执行的结果!!!,执行结果需要到返回通知里访问 // @After("controllerMethod() || serviceMethod()") // public void afterMethod(JoinPoint joinPoint) { // String className = joinPoint.getTarget().getClass().getName(); // String methodName = joinPoint.getSignature().getName(); // String msgInfo = "【" + className + "." + methodName + "】"; // logger.info(msgInfo + "...............end."); // } /** * @Description : 日志打印 * @author : 陈惟鲜 danger * @Date : 2018年8月8日 下午5:29:47 * @param point * @return * @throws Throwable */ @Around("controllerMethod() || serviceMethod()") public Object doAround(ProceedingJoinPoint point) throws Throwable { String msgInfo = "@aop["+point.getSignature().getDeclaringTypeName()+"."+point.getSignature().getName()+"]"; // 所在的类.方法 String requestStr = getRequestParam(point); requestStr = parameterHandle(requestStr, 10000); logger.info(msgInfo + "start.输入参数:" + requestStr); long startTime = System.currentTimeMillis();// 开始时间 Object result = null; try{ // 执行完方法的返回值:调用proceed()方法,就会触发切入点方法执行 result = point.proceed();// result的值就是被拦截方法的返回值 }catch(Exception e){ throw e; }finally{ long handleTime = System.currentTimeMillis()-startTime;// 开始时间 String responseStr = result==null?"无": JSON.toJSONString(result); responseStr = parameterHandle(responseStr, 10000); StringBuffer endString = new StringBuffer(100); endString.append(msgInfo).append("end."); endString.append("耗时(" + handleTime + "ms)"); endString.append("输出参数:").append(responseStr); logger.info(endString.toString()); } return result; } /** * @Description : 参数处理,超过指定长度字符的,只显示1000... * @author : 陈惟鲜 danger * @Date : 2018年8月10日 上午11:44:11 * @param paramStr * @param strlength * @return */ private String parameterHandle(String paramStr, int strlength){ if (paramStr.length() > strlength){ paramStr = paramStr.substring(0, 1000) + "..."; } if (paramStr.length() > 10){ paramStr = "[" + paramStr + "]"; } return paramStr; } /*** * @Description : 获取请求参数 * @author : 陈惟鲜 danger * @Date : 2018年8月9日 下午3:47:08 * @param point * @return */ private String getRequestParam(ProceedingJoinPoint point){ String class_name = point.getTarget().getClass().getName(); String method_name = point.getSignature().getName(); /** * 获取方法的参数值数组。 */ Object[] methodArgs = point.getArgs(); String[] paramNames = null; // 结果 String requestStr = ""; /** * 获取方法参数名称 */ try { paramNames = getFieldsName(class_name, method_name); requestStr = logParam(paramNames, methodArgs); } catch (Exception e) { requestStr = "获取参数失败"; } return requestStr; } /** * 使用javassist来获取方法参数名称 * @param class_name 类名 * @param method_name 方法名 * @return * @throws Exception */ private String[] getFieldsName(String class_name, String method_name) throws Exception { Class<?> clazz = Class.forName(class_name); String clazz_name = clazz.getName(); ClassPool pool = ClassPool.getDefault(); ClassClassPath classPath = new ClassClassPath(clazz); pool.insertClassPath(classPath); CtClass ctClass = pool.get(clazz_name); CtMethod ctMethod = ctClass.getDeclaredMethod(method_name); MethodInfo methodInfo = ctMethod.getMethodInfo(); CodeAttribute codeAttribute = methodInfo.getCodeAttribute(); LocalVariableAttribute attr = (LocalVariableAttribute) codeAttribute.getAttribute(LocalVariableAttribute.tag); if(attr == null){ return null; } String[] paramsArgsName = new String[ctMethod.getParameterTypes().length]; int pos = Modifier.isStatic(ctMethod.getModifiers()) ? 0 : 1; for (int i=0;i<paramsArgsName.length;i++){ paramsArgsName[i] = attr.variableName(i + pos); } return paramsArgsName; } /** * 判断是否为基本类型:包括String * @param clazz clazz * @return true:是; false:不是 */ private boolean isPrimite(Class<?> clazz){ if (clazz.isPrimitive() || clazz == String.class){ return true; }else { return false; } } /** * 打印方法参数值 基本类型直接打印,非基本类型需要重写toString方法 * @param paramsArgsName 方法参数名数组 * @param paramsArgsValue 方法参数值数组 */ private String logParam(String[] paramsArgsName,Object[] paramsArgsValue){ if(ArrayUtils.isEmpty(paramsArgsName) || ArrayUtils.isEmpty(paramsArgsValue)){ return ""; } StringBuffer buffer = new StringBuffer(); for (int i=0;i<paramsArgsValue.length;i++){ //参数名 String name = paramsArgsName[i]; //参数值 Object value = paramsArgsValue[i]; buffer.append(name +" = "); if(isPrimite(value.getClass())){ buffer.append(value + " ,"); }else { buffer.append(value.toString() + " ,"); } } return buffer.toString(); } }
原文地址:https://www.cnblogs.com/a393060727/p/9454281.html
时间: 2024-10-21 18:23:18