在本人的博文中,有一篇關於“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;
}
}