寫在前面
之前有寫過關於spring boot Aop使用之類的文章,傳送門,感興趣的同學可以,詳細查看文章。
這裏其實還是爲了方便調試,及日誌輸出使用。
使用實例
示例代碼如下:
package com.rongrong.wiki.aspect;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.support.spring.PropertyPreFilters;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
@Aspect
@Component
public class LogAspect {
private final static Logger LOG = LoggerFactory.getLogger(LogAspect.class);
/** 定義一個切點 */
@Pointcut("execution(public * com.rongrong.*.controller..*Controller.*(..))")
public void controllerPointcut() {}
@Before("controllerPointcut()")
public void doBefore(JoinPoint joinPoint) throws Throwable {
// 開始打印請求日誌
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
Signature signature = joinPoint.getSignature();
String name = signature.getName();
// 打印請求信息
LOG.info("------------- 開始 -------------");
LOG.info("請求地址: {} {}", request.getRequestURL().toString(), request.getMethod());
LOG.info("類名方法: {}.{}", signature.getDeclaringTypeName(), name);
LOG.info("遠程地址: {}", request.getRemoteAddr());
// 打印請求參數
Object[] args = joinPoint.getArgs();
// LOG.info("請求參數: {}", JSONObject.toJSONString(args));
Object[] arguments = new Object[args.length];
for (int i = 0; i < args.length; i++) {
if (args[i] instanceof ServletRequest
|| args[i] instanceof ServletResponse
|| args[i] instanceof MultipartFile) {
continue;
}
arguments[i] = args[i];
}
// 排除字段,敏感字段或太長的字段不顯示
String[] excludeProperties = {"password", "file"};
PropertyPreFilters filters = new PropertyPreFilters();
PropertyPreFilters.MySimplePropertyPreFilter excludefilter = filters.addFilter();
excludefilter.addExcludes(excludeProperties);
LOG.info("請求參數: {}", JSONObject.toJSONString(arguments, excludefilter));
}
@Around("controllerPointcut()")
public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
long startTime = System.currentTimeMillis();
Object result = proceedingJoinPoint.proceed();
// 排除字段,敏感字段或太長的字段不顯示
String[] excludeProperties = {"password", "file"};
PropertyPreFilters filters = new PropertyPreFilters();
PropertyPreFilters.MySimplePropertyPreFilter excludefilter = filters.addFilter();
excludefilter.addExcludes(excludeProperties);
LOG.info("返回結果: {}", JSONObject.toJSONString(result, excludefilter));
LOG.info("------------- 結束 耗時:{} ms -------------", System.currentTimeMillis() - startTime);
return result;
}
}
爲了查看效果,避免混淆影響,需要先註釋掉攔截器及過濾器部分相關代碼
重新編譯,啓動,查看結果如下:
到此,SpringBootAOP的使用分享完畢