AOP日志,记录调用类、方法、方法参数名称、方法参数值(包括对象和基本类型)

来源:互联网 发布:分期贷款的软件 编辑:程序博客网 时间:2024/05/16 09:10

AOP日志,记录调用类、方法、方法参数名称、方法参数值(包括对象和基本类型)


package com.paincupid.springmvc.log;import java.lang.reflect.Field;import java.lang.reflect.Method;import javassist.ClassClassPath;import javassist.ClassPool;import javassist.CtClass;import javassist.CtMethod;import javassist.Modifier;import javassist.NotFoundException;import javassist.bytecode.CodeAttribute;import javassist.bytecode.LocalVariableAttribute;import javassist.bytecode.MethodInfo;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.annotation.AfterReturning;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Pointcut;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.stereotype.Component;/** *  * @author arthur.paincupid.lee * @since 2016.04.17 */@Aspect@Componentpublic class SysLogWithOutAnn {private static final Logger logger = LoggerFactory.getLogger(SysLogWithOutAnn.class);private static String[] types = { "java.lang.Integer", "java.lang.Double","java.lang.Float", "java.lang.Long", "java.lang.Short","java.lang.Byte", "java.lang.Boolean", "java.lang.Char","java.lang.String", "int", "double", "long", "short", "byte","boolean", "char", "float" };@Pointcut("execution(* com.paincupid.springmvc.*.controller.*.search*(..))")public void searchControllerCall() {}@AfterReturning(value = "searchControllerCall()", argNames = "rtv", returning = "rtv")public void searchControllerCallCalls(JoinPoint joinPoint, Object rtv)throws Throwable {System.out.println("---------------");String classType = joinPoint.getTarget().getClass().getName();Class<?> clazz = Class.forName(classType);String clazzName = clazz.getName();String clazzSimpleName = clazz.getSimpleName();String methodName = joinPoint.getSignature().getName();String[] paramNames = getFieldsName(this.getClass(), clazzName, methodName);String logContent = writeLogInfo(paramNames, joinPoint);Logger logger = LoggerFactory.getLogger(clazzName);logger.info("clazzName: "+clazzName+", methodName:"+methodName+", param:"+ logContent);}private static String writeLogInfo(String[] paramNames, JoinPoint joinPoint){Object[] args = joinPoint.getArgs();StringBuilder sb = new StringBuilder();boolean clazzFlag = true;for(int k=0; k<args.length; k++){Object arg = args[k];sb.append(paramNames[k]+" ");// 获取对象类型String typeName = arg.getClass().getTypeName();for (String t : types) {if (t.equals(typeName)) {sb.append("=" + arg+"; ");}}if (clazzFlag) {sb.append(getFieldsValue(arg));}}return sb.toString();}/** * 得到方法参数的名称 * @param cls * @param clazzName * @param methodName * @return * @throws NotFoundException */private static String[] getFieldsName(Class cls, String clazzName, String methodName) throws NotFoundException{ClassPool pool = ClassPool.getDefault();//ClassClassPath classPath = new ClassClassPath(this.getClass());ClassClassPath classPath = new ClassClassPath(cls);pool.insertClassPath(classPath);CtClass cc = pool.get(clazzName);CtMethod cm = cc.getDeclaredMethod(methodName);MethodInfo methodInfo = cm.getMethodInfo();CodeAttribute codeAttribute = methodInfo.getCodeAttribute();LocalVariableAttribute attr = (LocalVariableAttribute) codeAttribute.getAttribute(LocalVariableAttribute.tag);if (attr == null) {// exception}String[] paramNames = new String[cm.getParameterTypes().length];int pos = Modifier.isStatic(cm.getModifiers()) ? 0 : 1;for (int i = 0; i < paramNames.length; i++){paramNames[i] = attr.variableName(i + pos);//paramNames即参数名}return paramNames;}/** * 得到参数的值 * @param obj */public static String getFieldsValue(Object obj) {Field[] fields = obj.getClass().getDeclaredFields();String typeName = obj.getClass().getTypeName();for (String t : types) {if(t.equals(typeName))return "";}StringBuilder sb = new StringBuilder();sb.append("【");for (Field f : fields) {f.setAccessible(true);try {for (String str : types) {if (f.getType().getName().equals(str)){sb.append(f.getName() + " = " + f.get(obj)+"; ");}}} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}}sb.append("】");return sb.toString();}/** * 得到用户的登陆信息--这个还未实现,只是在网上抄的一段 * @param joinPoint * @throws Exception */public void adminOptionContent(JoinPoint joinPoint) throws Exception {StringBuffer rs = new StringBuffer();String className = null;int index = 1;Object[] args = joinPoint.getArgs();for (Object info : args) {// 获取对象类型className = info.getClass().getName();className = className.substring(className.lastIndexOf(".") + 1);rs.append("[参数" + index + ",类型:" + className + ",值:");// 获取对象的所有方法Method[] methods = info.getClass().getDeclaredMethods();// 遍历方法,判断get方法for (Method method : methods) {String methodName = method.getName();System.out.println(methodName);// 判断是不是get方法if (methodName.indexOf("get") == -1) {// 不是get方法continue;// 不处理}Object rsValue = null;try {// 调用get方法,获取返回值rsValue = method.invoke(info);if (rsValue == null) {// 没有返回值continue;}} catch (Exception e) {continue;}// 将值加入内容中rs.append("(" + methodName + " : " + rsValue + ")");}rs.append("]");index++;}System.out.println(rs.toString());}private void getParamterName(String clazzName, String methodName)throws NotFoundException {ClassPool pool = ClassPool.getDefault();ClassClassPath classPath = new ClassClassPath(this.getClass());pool.insertClassPath(classPath);CtClass cc = pool.get(clazzName);CtMethod cm = cc.getDeclaredMethod(methodName);MethodInfo methodInfo = cm.getMethodInfo();CodeAttribute codeAttribute = methodInfo.getCodeAttribute();LocalVariableAttribute attr = (LocalVariableAttribute) codeAttribute.getAttribute(LocalVariableAttribute.tag);if (attr == null) {// exception}String[] paramNames = new String[cm.getParameterTypes().length];int pos = Modifier.isStatic(cm.getModifiers()) ? 0 : 1;for (int i = 0; i < paramNames.length; i++)paramNames[i] = attr.variableName(i + pos);// paramNames即参数名for (int i = 0; i < paramNames.length; i++) {System.out.println(paramNames[i]);}}}

在xml中别忘记加入:<aop:aspectj-autoproxy proxy-target-class="true" />

<?xml version="1.0" encoding="UTF-8"?><beans:beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"xmlns:beans="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"xmlns="http://www.springframework.org/schema/mvc"xsi:schemaLocation="                 http://www.springframework.org/schema/aop     http://www.springframework.org/schema/aop/spring-aop-3.1.xsd                 http://www.springframework.org/schema/beans   http://www.springframework.org/schema/beans/spring-beans.xsd                 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd                 http://www.springframework.org/schema/mvc     http://www.springframework.org/schema/mvc/spring-mvc.xsd             "default-autowire="byName"><!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure --><!-- Enables the Spring MVC @Controller programming model --><annotation-driven /><!-- 最重要:::如果放在spring-context.xml中,这里的aop设置将不会生效 true使用cgLib代理,false使用jdk代理--><aop:aspectj-autoproxy proxy-target-class="true" /><!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory --><resources mapping="/resources/**" location="/resources/" /><!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory --><beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><beans:property name="prefix" value="/WEB-INF/views/" /><beans:property name="suffix" value=".jsp" /></beans:bean><context:component-scan base-package="com.paincupid.springmvc" /><!-- 支持文件上传 --><beans:bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></beans:bean></beans:beans>


结果:

[tomcat-http--6] INFO com.paincupid.springmvc.json.controller.JqueryFormPluginSimpleController - clazzName: com.paincupid.springmvc.json.controller.JqueryFormPluginSimpleController, methodName:searchForm, param:person 【id = lele李; name = lee李 - beforeSerialize; age = 0; tel = null; prov = null; city = null; town = null; sex = null; location = null; company = null; comment = 呵呵ll123444; 】currentPage =1; [tomcat-http--7] INFO com.paincupid.springmvc.finance.controller.FinanceController - clazzName: com.paincupid.springmvc.finance.controller.FinanceController, methodName:searchFinance, param:fid =-1; consumerProject =1; consumer =1; forwho =12; consumerDateBegin =2016-04-01; consumerDateEnd =2016-04-30; feeLess =200; feeGreater =100; currentPage =1; 

[tomcat-http--6] INFO com.paincupid.springmvc.json.controller.JqueryFormPluginSimpleController - clazzName: com.paincupid.springmvc.json.controller.JqueryFormPluginSimpleController, methodName:searchForm, param:person 【id = lele李; name = lee李 - beforeSerialize; age = 0; tel = null; prov = null; city = null; town = null; sex = null; location = null; company = null; comment = 呵呵ll123444; 】currentPage =1;
[tomcat-http--7] INFO com.paincupid.springmvc.finance.controller.FinanceController - clazzName: com.paincupid.springmvc.finance.controller.FinanceController, methodName:searchFinance, param:fid =-1; consumerProject =1; consumer =1; forwho =12; consumerDateBegin =2016-04-01; consumerDateEnd =2016-04-30; feeLess =200; feeGreater =100; currentPage =1;

在这之前,要引入

<!-- AspectJ --><dependency><groupId>org.aspectj</groupId><artifactId>aspectjrt</artifactId><version>${org.aspectj-version}</version></dependency><!-- javassist  --><dependency><groupId>org.javassist</groupId><artifactId>javassist</artifactId><version>3.20.0-GA</version></dependency>



代码下载:https://git.oschina.net/paincupid/springmvc/tree/bootstrap

转载请注明出处:http://blog.csdn.net/paincupid

1 0
原创粉丝点击