国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - Java教程 - spring boot 使用Aop通知打印控制器請求報文和返回報文問題

spring boot 使用Aop通知打印控制器請求報文和返回報文問題

2021-04-21 14:44淺淺_淺默 Java教程

這篇文章主要介紹了spring-boot 使用Aop通知打印控制器請求報文和返回報文,非常不錯,具有參考借鑒價值,需要的朋友可以參考下

一、簡介

開發(fā)過程中我們往往需要寫許多例如: 

?
1
2
3
4
5
6
7
8
@getmapping("/id/get")
  public result getbyid( string id) throws exception{
    log.info("請求參數(shù)為:"+id);
    verify(new verifyparam("部門id", id));
    result result = new result("通過id獲取部門信息成功!", service.querybyid(id));
    log.info("返回報文為:"+result.tostring());
    return result;
  }

打印請求參數(shù)以及返回參數(shù)的方法,而這些操作存在于每個方法之中,使得我們代碼較為冗余,為此我們可以通過動態(tài)代理將打印參數(shù)和打印返回報文作為切面,使用切入點表達式將其切入至每個方法之中。

二、步驟

1、引入aop相關(guān)的依賴:

?
1
2
3
4
5
<!--aop相關(guān)的依賴-->
<dependency>
  <groupid>org.springframework.boot</groupid>
  <artifactid>spring-boot-starter-aop</artifactid>
</dependency>

引入依賴后spring-aop會加載其需要的依賴,spring默認使用aspectj實現(xiàn)通知

其中aspectjweaver.jar中包含了解析aspectj切入點表達式的文件,使用切入點表達式處理事務(wù)的時候也需要加入此依賴。

2、配置:

1)、創(chuàng)建配置類:

?
1
2
3
4
5
6
7
8
/**
 * @功能描述:用于controller層操作的aop類
 * @author administrator
 */
@component // 將對象交由spring進行管理
@aspect // 代表此類為一個切面類
public class controlleraop {
}

其中@aspect 注解代表其為一個切面管理類,可以在其下定義切入點表達式,aspectj框架會進行解析。

2)、定義切入點表達式:

?
1
2
3
@pointcut("execution(public * com.hzt.manage.*.web.controller..*.*(..))") // 切入點表達式
  public void privilege() {
  }

其中,@pointcut代表此方法為一個切入點表達式。其value值為切入點表達式,其中value可以省略其大致格式為:

  @注解(表達標簽+表達式格式)
的格式,spring aop支持的aspectj切入點指示符如下:

1、 execution:用于匹配方法執(zhí)行的連接點;

2、within:用于匹配指定類型內(nèi)的方法執(zhí)行;

3、this:用于匹配當前aop代理對象類型的執(zhí)行方法;注意是aop代理對象的類型匹配,這樣就可能包括引入接口也類型匹配;

4、target:用于匹配當前目標對象類型的執(zhí)行方法;注意是目標對象的類型匹配,這樣就不包括引入接口也類型匹配;

5、args:用于匹配當前執(zhí)行的方法傳入的參數(shù)為指定類型的執(zhí)行方法;

6、@within:用于匹配所以持有指定注解類型內(nèi)的方法;

7、@target:用于匹配當前目標對象類型的執(zhí)行方法,其中目標對象持有指定的注解;

8、@args:用于匹配當前執(zhí)行的方法傳入的參數(shù)持有指定注解的執(zhí)行;

9、@annotation:用于匹配當前執(zhí)行方法持有指定注解的方法;

10、bean:spring aop擴展的,aspectj沒有對于指示符,用于匹配特定名稱的bean對象的執(zhí)行方法;

11、reference pointcut:表示引用其他命名切入點,只有@apectj風格支持,schema風格不支持。

args中定義了切入點表達式方法執(zhí)行時候的參數(shù):

?
1
2
3
@pointcut(value="execution(public * com.hzt.manage.*.web.controller..*.*(..))&&args(param)",argnames="param") // 切入點表達式
public void privilege1(string param) {
}

我們重點介紹 execution 方法連接點的表達式,其大概結(jié)構(gòu)為:

?
1
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern)throws-pattern?)

1、修飾符匹配(modifier-pattern?)(可省略)

2、返回值匹配(ret-type-pattern)可以為*表示任何返回值 ,如 (string) 代表只篩選返回string類型的切入點 ,全路徑的類名等(不可省略)

3、類路徑匹配(declaring-type-pattern?)如*.manage代表一級包為任意,二級包為manage的名稱。*..manage代表所有manage包下的子類包。com..*.comtroller代表com包下所有的controller包等,*代表所有包都匹配。(不可省略)

4、方法名匹配(name-pattern)可以指定方法名 或者 *代表所有, get* 代表以get開頭的所有方法,也可指定前綴*get代表任意后綴為get的方法(不可省略)

5、參數(shù)匹配((param-pattern))可以指定具體的參數(shù)類型,多個參數(shù)間用“,”隔開,各個參數(shù)也可以用“*”來表示匹配任意類型的參數(shù),如(string)表示匹配一個string參數(shù)的方法;(*,string) 表示匹配有兩個參數(shù)的方法,第一個參數(shù)可以是任意類型,而第二個參數(shù)是string類型;可以用(..)表示任意參數(shù)(不可省略)

6、異常類型匹配(throws-pattern?)

3、定義切面方法

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
@around("privilege()")
  public object around(proceedingjoinpoint pjd) throws throwable {
    // 獲取方法名
    string classname = pjd.getsignature().getclass().getname();
    // 獲取執(zhí)行的方法名稱
    string methodname = pjd.getsignature().getname();
    /** 初始化日志打印 */
    logger log = loggerfactory.getlogger(classname);
    // 定義返回參數(shù)
    object result = null;
    // 記錄開始時間
    long start = system.currenttimemillis();
    // 獲取方法參數(shù)
    object[] args = pjd.getargs();
    string params = "前端請求參數(shù)為:";
    //獲取請求參數(shù)集合并進行遍歷拼接
    for (object object : args) {
      params += object.tostring() + ",";
    }
    params = params.substring(0, params.length() - 1);
    //打印請求參數(shù)參數(shù)
    log.info(classname+"類的"+methodname + "的" + params);
    // 執(zhí)行目標方法
    result = pjd.proceed();
    // 打印返回報文
    log.info("方法返回報文為:" + (result instanceof result ? (result) result : result));
    // 獲取執(zhí)行完的時間
    log.info(methodname + "方法執(zhí)行時長為:" + (system.currenttimemillis() - start));
    return result;
  }

5、@around 環(huán)繞通知,如上代碼所示便是環(huán)繞通知,其有proceedingjoinpoint參數(shù)

其中 pjd.proceed();方法代表去執(zhí)行目標方法,并獲得一個object類型的返回值 ,我們可以對返回值進行加工處理,如裝飾加工等。

return的值為方法執(zhí)行的結(jié)果。上述代碼中首先獲取類名、方法名、方法請求參數(shù)等,進行打印的拼接,并且記錄方法執(zhí)行的開始時間,并進行打印至日志。

然后執(zhí)行方法,獲取到方法返回結(jié)果,進行打印執(zhí)行時間和執(zhí)行結(jié)果。

最后返回執(zhí)行結(jié)果。即使用aop打印請求報文和返回報文的aop切面編碼結(jié)束。

其中@around代表其為一個環(huán)繞通知方法,其有以下幾種類型:

1、@before前置通知,擁有請求參數(shù) joinpoint ,用來連接當前連接點的連接細節(jié),一般包括方法名和參數(shù)值。在方法執(zhí)行前進行執(zhí)行方法體,不能改變方法參數(shù),也不能改變方法執(zhí)行結(jié)果。

?
1
2
3
@before(value = "privilege()")
public void before(joinpoint joinpoint) {
}

2、@after 后置通知:在目標方法執(zhí)行之后,無論是否發(fā)生異常,都進行執(zhí)行的通知。在后置通知中,不能訪問目標方法的執(zhí)行結(jié)果(因為有可能發(fā)生異常),不能改變方法執(zhí)行結(jié)果。

?
1
2
3
@before(value = "privilege()")
  public void after(joinpoint joinpoint) {   
  }

3、@afterreturning 返回通知,在目標方法執(zhí)行結(jié)束時,才執(zhí)行的通知,同后置方法相同。其能訪問方法執(zhí)行結(jié)果(因為正常執(zhí)行)和方法的連接細節(jié),但是不能改變方法執(zhí)行結(jié)果。

?
1
2
3
@afterreturning(value = "privilege()")
public void afterreturing(joinpoint joinpoint,object result) {
}

result中存放的為方法的返回值。

4、@afterthrowing 異常通知:在目標方法出現(xiàn)異常時才會進行執(zhí)行的代碼。 throwing屬性代表方法體執(zhí)行時候拋出的異常,其值一定與方法中exception的值需要一致。

?
1
2
3
@afterthrowing(value="privilege()",throwing="ex")
public void exce(joinpoint joinpoint, exception ex) {   
}

三、測試

編寫一個controller方法

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@restcontroller
@requestmapping("/api/v1/dept")
public class deptcontroller extends basecontroller{
  /** 日志記錄類 */
  private logger log = loggerfactory.getlogger(getclass());
  /** 自家的service */
  @autowired
  private deptservice service;
  /**
   * @功能描述:根據(jù)id查詢部門內(nèi)容的方法
   * @return dept
   */
  @getmapping("/id/get")
  public result getbyid( string id) throws exception{
    verify(new verifyparam("部門id", id));
    return new result("通過id獲取部門信息成功!", service.querybyid(id));
  }
}

如此我們的controller層中的方法就大大的簡潔了。

測試結(jié)果:

2018-04-10 22:59:27.468  info 1460 --- [nio-8088-exec-5] nproceedingjoinpoint$methodsignatureimpl : getbyid的前端請求參數(shù)為:22
2018-04-10 22:59:27.470  info 1460 --- [nio-8088-exec-5] nproceedingjoinpoint$methodsignatureimpl : 方法返回報文為:result [result_code=suc, result_message=通過id獲取部門信息成功!, data=dept [id=22, no=22, name=22, manager=22, description=22, phone=22, createtime=thu apr 19 23:38:37 cst 2018, edittime=null]]
2018-04-10 22:59:27.470  info 1460 --- [nio-8088-exec-5] nproceedingjoinpoint$methodsignatureimpl : getbyid方法執(zhí)行時長為:2

如此便能很雅觀簡潔隱式的打印請求參數(shù)、返回結(jié)果和執(zhí)行時間等!

原文鏈接:http://www.cnblogs.com/zeryts/p/8784172.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 亚洲综合色成在线播放 | 欧美日韩亚洲一区二区三区 | 久久精品国产精品青草 | 国产精品久久久久久久久小说 | 亚洲视频 欧美视频 | 日韩免费高清在线 | 久久精彩视频 | 黄色在线网站 | 免费一级网站 | 国产毛片区 | 91精品久久久久久久久久久久久久久 | 天天操导航 | 丁香婷婷综合激情五月色 | 久久免费国产精品 | 亚洲国产精品自拍 | 色噜噜视频| 国产精品资源在线 | 欧洲精品视频在线观看 | 国产精品69毛片高清亚洲 | 亚洲高清免费视频 | 日韩欧美一级片 | 久久久久久久久久久免费视频 | 自拍偷拍小视频 | 一级视频免费观看 | 精品亚洲成a人在线观看 | 亚洲一区在线免费观看 | 黄片毛片毛片毛片 | 久久久91精品国产一区二区三区 | av超碰 | 久久国产精品无码网站 | 天天操导航 | 一区二区三区日本 | 亚洲视频免费观看 | ts人妖另类精品视频系列 | 黑人精品 | 成人伊人 | 永久91嫩草亚洲精品人人 | 中文字幕国产视频 | 国产一区二区三区视频在线观看 | 国产成人一区二区 | 欧美精品亚洲精品日韩精品 |