在本人的博文中,有一篇关于“Spring 自动打日志”的博文,今天想对其添加一个 针对 某个方法,取消对其打印日志的想法。因此计划使用注解方式,对不想打印日志的方法进行标记。
Spring 自动打日志
首先定义注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author qi.liu
* @create 2019-06-12 16:40
* @desc 描述:不需要打日志的注解
**/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface NotNeedLog {
boolean closeLogStatus() default true;
}
其次在不想打印日志的方法上加上注解。类似:
@NotNeedLog
@Override
public Boolean checkWillAwardChallenge(ChallengeInfo challengeInfo) {
xxxxxxxxxxxxxx
}
在我的实现MethodInterceptor的方法中。想得到这个注解 notNeedLog 对象却一直为null。
NotNeedLog notNeedLog = invocation.getMethod().getAnnotation(NotNeedLog.class);
经过分析,Spring在处理中,可能是因为我的项目有事务,serviceImpl的方法被代理后直接得不到了。换一个思路:先得到自己的父类,然后通过父类得到真实的自己
Method method = invocation.getThis().getClass().getDeclaredMethod(invocation.getMethod().getName(),invocation.getMethod().getParameterTypes());
NotNeedLog notNeedLog = method.getAnnotation(NotNeedLog.class);
这时候的notNeedLog 就不是null了。
完整的打印日志类贴一下。具体的日志配置请参照 https://blog.csdn.net/u013476435/article/details/81984605 中的配置
import com.alibaba.dubbo.common.utils.StringUtils;
import com.alibaba.fastjson.JSON;
import net.okdi.o2o.core.common.NotNeedLog;
import net.okdi.o2o.core.util.PubMethod;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.StopWatch;
import java.lang.reflect.Method;
/**
* @author qi.liu
* @create 2018-08-23 16:48
* @desc 描述:打日志
**/
public class MethodLogAdvice implements MethodInterceptor {
public final Integer subLogLength = 1000;
/**
* 拦截要执行的目标方法
*/
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
//用 commons-lang 提供的 StopWatch 计时,Spring 也提供了一个 StopWatch
StopWatch clock = new StopWatch();
clock.start(); //计时开始
Object result = invocation.proceed();
clock.stop(); //计时结束
try {
/**
* NotNeedLog notNeedLog = invocation.getMethod().getAnnotation(NotNeedLog.class);
*
* 这个方法帮忙拿出注解中的operation属性
* * 因为有拦截serviceImpl的方法,而这些方法又加了事务管理,也就是这里也有aop,这些已经是代理类,用之前的写法获得的是代理类的方法,而这些
* * 方法是特么不会把父类中的方法的注解加上去的!!!
*
*/
Method method = invocation.getThis().getClass().getDeclaredMethod(invocation.getMethod().getName(),invocation.getMethod().getParameterTypes());
NotNeedLog notNeedLog = method.getAnnotation(NotNeedLog.class);
if (!PubMethod.isEmpty(notNeedLog) && notNeedLog.closeLogStatus()) {
//如果为true 那么就不需要打印日志
} else {
//方法参数类型,转换成简单类型
Class[] params = invocation.getMethod().getParameterTypes();
String[] simpleParams = new String[params.length];
for (int i = 0; i < params.length; i++) {
String args = "";
if (invocation.getArguments().length > i) {
Object o = invocation.getArguments()[i];
if (!PubMethod.isEmpty(o)) {
args = o.toString();
}
}
simpleParams[i] = params[i].getSimpleName() + "->[" + args + "]";
}
String resultJson = JSON.toJSONString(result);
if (!PubMethod.isEmpty(resultJson) && resultJson.length() > subLogLength) {
resultJson = resultJson.substring(0, subLogLength) + "......(已省略" + (resultJson.length() - subLogLength) + "个字符)";
}
LogFactory.getLog(invocation.getThis().getClass()).info("耗时" + clock.getTotalTimeSeconds() + "秒," + invocation.getMethod().getName() + "(" + StringUtils.join(simpleParams, ",") + ")" + "结果:" + resultJson);
}
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
}