javascript
SpringBoot中使用AOP打印接口日志的方法(转载)
前言
AOP 是 Aspect Oriented Program (面向切面)的編程的縮寫。他是和面向對象編程相對的一個概念。在面向對象的編程中,我們傾向于采用封裝、繼承、多態等概念,將一個個的功能在對象中來實現。但是,我們在實際情況中也發現,會有另外一種需求就是一類功能在很多對象的很多方法中都有需要。例如有一些對數據庫訪問的方法有事務管理的需求,有很多方法中要求打印日志。按照面向對象的方式,那么這些相同的功能要在很多地方來實現或者在很多地方來調用。這就非常繁瑣并且和這些和業務不相關的需求耦合太緊密了。所以后來就出現了面向切面的編程來解決這一類問題,并對面向對象的編程做了很好的補充
概念
要很好的理解面向切面的編程,先要理解 AOP 的一些概念。在 Java 中 AspectJ 比較完整的實現了 AOP 的功能,但是使用起來也比較復,所以這里主要是討論 Spring 的 AOP 。Spring AOP 采用簡單夠用的原則,實現了 AOP 的核心功能。下面先說說 AOP 中的具體概念
SprinBoot AOP 實現
前面我們已經用好幾章講述了 SpringBoot 的基本使用。那么這里我們就用 SpringBoot 和 AOP 結合來實現一個輸出所有 Rest 接口輸入參數和返回參數的日志的功能。
實現 rest 服務功能。
根據前面的文章,我們先建立一個 SpingBoot 的工程如下圖所示
demo 工程
SpringBoot 項目配置
我們對 SpringBoot 項目配置如下
?| 1 2 3 4 5 6 7 8 9 10 11 12 | server: ?port: 3030 ?servlet: ??context-path: /aop-demo spring: ?jackson: ??date-format: yyyy-MM-dd HH:mm:ss ??serialization: ???indent-output: true logging: ?level: ??com.yanggch: debug |
其中 jackson 相關配置是為了將對象輸出成 json 字符串后能夠格式化輸出
先在我們要通過 AOP 功能將所有 Rest 接口的輸入參數和返回結果輸出到日志中。
實現 Web Aop 功能。
@Aspect@Component
public class WebLogAspect {
private static Logger log = LoggerFactory.getLogger(WebLogAspect.class);
private final ObjectMapper mapper;
@Autowired
public WebLogAspect(ObjectMapper mapper) {
this.mapper = mapper;
}
@Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping)")
public void webLog() {
}
@Before("webLog()")
public void doBefore(JoinPoint joinPoint) {
for (Object object : joinPoint.getArgs()) {
if (
object instanceof MultipartFile
|| object instanceof HttpServletRequest
|| object instanceof HttpServletResponse
) {
continue;
}
try {
if (log.isInfoEnabled()) {
log.info(
joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName()
+ " : request parameter : " + mapper.writeValueAsString(object)
);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
@AfterReturning(returning = "response", pointcut = "webLog()")
public void doAfterReturning(Object response) throws Throwable {
if (response != null) {
log.info("response parameter : " + mapper.writeValueAsString(response));
}
}
}
這里有幾個需要注意的地方,
測試
在前臺通過 postman 發起請求,后臺日志輸入結果如下
2018-05-27 19:58:42.941 DEBUG 86072 --- [nio-3030-exec-4] c.yanggch.demo.aop.comment.WebLogAspect? : com.yanggch.demo.aop.web.SecurityApi.login : request parameter : {
? "account" : "yanggch",
? "pwd" : "123456"
}
2018-05-27 19:58:42.941 DEBUG 86072 --- [nio-3030-exec-4] c.yanggch.demo.aop.comment.WebLogAspect? : com.yanggch.demo.aop.web.SecurityApi.login : request parameter : 2001
2018-05-27 19:58:42.942 DEBUG 86072 --- [nio-3030-exec-4] c.yanggch.demo.aop.comment.WebLogAspect? : response parameter : {
? "shopId" : 2001,
? "account" : "yanggch",
? "pwd" : "123456",
? "loginTime" : "2018-05-27 11:58:42"
}
2018-05-27 19:58:45.796 DEBUG 86072 --- [nio-3030-exec-5] c.yanggch.demo.aop.comment.WebLogAspect? : com.yanggch.demo.aop.web.SecurityApi.echo : request parameter : "yanggch"
2018-05-27 19:58:45.796 DEBUG 86072 --- [nio-3030-exec-5] c.yanggch.demo.aop.comment.WebLogAspect? : response parameter : "hello,yanggch"
由此可見,我們雖然沒有在 rest 接口方法中寫輸出日志的代碼,但是通過 AOP 的方式可以自動的給各個 rest 入口方法中添加上輸出入口參數和返回參數的代碼并正確執行。
其他說明
前面提到了 Advice 的類型和 Pointcut 的 AOP 表達式語言。具體參考如下。
Advice 類型
AOP 表達式語言
1、方法參數匹配
@args()
2、方法描述匹配
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern)throws-pattern?)
其中 returning type pattern,name pattern, and parameters pattern是必須的.
. ret-type-pattern:可以為表示任何返回值,全路徑的類名等.
*. name-pattern:指定方法名, *代表所有
.set代表以set開頭的所有方法.
. parameters pattern:指定方法參數(聲明的類型),(..)代表所有參數,()代表一個參數
. (,String)代表第一個參數為任何值,第二個為String類型.
3、當前AOP代理對象類型匹配
4、目標類匹配
@target()
@within()
5、標有此注解的方法匹配
@annotation()
ps:沒有打印出來的看看自己設置的日志級別
轉載于:https://www.cnblogs.com/liukunjava/p/9566965.html
總結
以上是生活随笔為你收集整理的SpringBoot中使用AOP打印接口日志的方法(转载)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux中设置vi编辑器的编码格式以及
- 下一篇: javascript基本数据类型问题汇总