最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

spring-boot使用AOP統(tǒng)一處理日志

 更新時(shí)間:2021年06月15日 14:26:28   作者:賀小五  
這篇文章主要為大家詳細(xì)介紹了spring-boot使用AOP統(tǒng)一處理日志,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

AOP我想大家都很清楚,有時(shí)候我們需要處理一些請(qǐng)求日志,或者對(duì)某些方法進(jìn)行一些監(jiān)控,如果出現(xiàn)例外情況應(yīng)該進(jìn)行怎么樣的處理,現(xiàn)在,我們從spring-boot中引入AOP.

[開發(fā)環(huán)境:jdk版本號(hào)為1.8,spring
boot的版本號(hào)為1.4.1]{style=”background-color:#FF0000”}

首先,我們先引入jar包,

POM文件添加如下內(nèi)容:

<!--引用AOP-->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!--引用GSON,用于打印-->
<dependency>
  <groupId>com.google.code.gson</groupId>
  <artifactId>gson</artifactId>
  <version>2.7</version>
</dependency>

引入jar包后,我們?cè)赽oot的啟動(dòng)方法,增加兩個(gè)簡(jiǎn)單的請(qǐng)求處理方法:

@SpringBootApplication(scanBasePackages = {"com"})
@RestController
public class DemoApplication{
  public static void main(String[] args) {
   SpringApplication.run(DemoApplication.class, args);
  }
  //測(cè)試無(wú)參的get請(qǐng)求
  @RequestMapping(value = "/testAspect",method = RequestMethod.GET)
  public UserVo test(){
   UserVo userVo = new UserVo();
   userVo.setAge("23");
   userVo.setName("賀小五");
   userVo.setSex("男");
   return userVo;
  }
  //測(cè)試有參的get請(qǐng)求,讓aop打印參數(shù)內(nèi)容
  @RequestMapping(value = "/testAspectArgs",method = RequestMethod.GET)
  public UserVo test(String name,String age,String sex){
   UserVo userVo = new UserVo();
   userVo.setName(name);
   userVo.setAge(age);
   userVo.setSex(sex);
   return userVo;
  }

增加了兩個(gè)簡(jiǎn)單的處理請(qǐng)求方法后,我們來(lái)增加我們的aop

/**
 * 項(xiàng)目名:SpringBootDemo
 * 創(chuàng)建人:賀小五
 * 創(chuàng)建時(shí)間:16/12/4 下午7:05
 * 類名:AspectDemo
 * 類描述:
 */
//申明是個(gè)切面
@Aspect
//申明是個(gè)spring管理的bean
@Component
@Order(1)
public class AspectDemo {
  private Logger log = Logger.getLogger(getClass());
  private Gson gson = new Gson();
  //申明一個(gè)切點(diǎn) 里面是 execution表達(dá)式
  @Pointcut("execution(public * com.example.DemoApplication.*(..))")
  private void controllerAspect(){}
  //請(qǐng)求method前打印內(nèi)容
  @Before(value = "controllerAspect()")
  public void methodBefore(JoinPoint joinPoint){
   ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
   HttpServletRequest request = requestAttributes.getRequest();
   //打印請(qǐng)求內(nèi)容
   log.info("===============請(qǐng)求內(nèi)容===============");
   log.info("請(qǐng)求地址:"+request.getRequestURL().toString());
   log.info("請(qǐng)求方式:"+request.getMethod());
   log.info("請(qǐng)求類方法:"+joinPoint.getSignature());
   log.info("請(qǐng)求類方法參數(shù):"+ Arrays.toString(joinPoint.getArgs()));
   log.info("===============請(qǐng)求內(nèi)容===============");
  }
  //在方法執(zhí)行完結(jié)后打印返回內(nèi)容
  @AfterReturning(returning = "o",pointcut = "controllerAspect()")
  public void methodAfterReturing(Object o ){
   log.info("--------------返回內(nèi)容----------------");
   log.info("Response內(nèi)容:"+gson.toJson(o));
   log.info("--------------返回內(nèi)容----------------");
  }

兩者配置好之后,接下來(lái),我們請(qǐng)求,然后查看打印日志,首先,啟動(dòng)我們的容器,然后我們先請(qǐng)求有參的處理請(qǐng)求方法的,打印日志如下:

{width=”1232”
height=”132”}

可以發(fā)現(xiàn),請(qǐng)求的url,method,以及args參數(shù)的值,還有類型,以及返回的內(nèi)容都打印出來(lái)了,說(shuō)明,這是AOP攔截成功了.

接下來(lái),我們測(cè)試下請(qǐng)求無(wú)參的處理請(qǐng)求方法,打印日志如下:

{width=”1100”
height=”130”}

我們可以發(fā)現(xiàn),這個(gè)方法,打印的方法參數(shù)是個(gè)空數(shù)組,是因?yàn)榉椒ú恍枰獏?shù)傳遞.

以上就是springboot引用aop進(jìn)行處理web的日志處理,下面將添加AOP切面的主要幾個(gè)注解,下面只是對(duì)注解的描述跟使用,具體測(cè)試,作者就不進(jìn)行測(cè)試了,各位看官有興趣的話,可以自己測(cè)試一下:

類注解:

@Aspect將一個(gè)類定義為一個(gè)切面類
@order(i)標(biāo)記切面類的處理優(yōu)先級(jí),i值越小,優(yōu)先級(jí)別越高.PS:可以注解類,也能注解到方法上

方法注解:

@Pointcut定義一個(gè)方法為切點(diǎn)里面的內(nèi)容為一個(gè)表達(dá)式,下面詳細(xì)介紹
@Before 在切點(diǎn)前執(zhí)行方法,內(nèi)容為指定的切點(diǎn)
@After 在切點(diǎn)后,return前執(zhí)行,
@AfterReturning在切入點(diǎn),return后執(zhí)行,如果想對(duì)某些方法的返回參數(shù)進(jìn)行處理,可以在這操作
@Around 環(huán)繞切點(diǎn),在進(jìn)入切點(diǎn)前,跟切點(diǎn)后執(zhí)行
@AfterThrowing 在切點(diǎn)后拋出異常進(jìn)行處理
@order(i) 標(biāo)記切點(diǎn)的優(yōu)先級(jí),i越小,優(yōu)先級(jí)越高

@Pointcut注解組合使用:

上面代碼中,我們定義了一個(gè)切點(diǎn),該切點(diǎn)只進(jìn)行處理指定路徑的:

@Pointcut("execution(public * com.example.DemoApplication.*(..))")
private void controllerAspect(){}

現(xiàn)在,我們?cè)诙x一個(gè)處理其他路徑下的切點(diǎn):

@Pointcut("execution(public * com.demo.*.*(..))")
private void controllerDemo(){}

以上切點(diǎn),都是分別處理不同的內(nèi)容,如果我們需要一個(gè)切點(diǎn)來(lái)處理他們兩者,我們可以這么配置:

@Pointcut(value = "controllerAspect()||controllerDemo()")
private void all(){}

在@Pointcut注解內(nèi),直接引用其它被@Pointcut注解過(guò)的方法名稱,這樣,該切點(diǎn)就可以處理兩個(gè)路徑下的方法

@Pointcut注解中的execution表達(dá)式: public * com.demo.*.*(..)

第一個(gè) public 表示方法的修飾符,可以用*代替
第一個(gè) * 表示 返回值,*代表所有
com.demo.* 包路徑,.*表示路徑下的所有包
第三個(gè).* 表示路徑下,所有包下的所有類的方法
(..) 表示不限方法參數(shù)

關(guān)于@order(i)注解的一些注意事項(xiàng):

注解類,i值是,值越小,優(yōu)先級(jí)越高
注解方法,分兩種情況
注解的是 @Before 是i值越小,優(yōu)先級(jí)越高
注解的是 @After或者@AfterReturning 中,i值越大,優(yōu)先級(jí)越高

總結(jié)兩者的概括就是:
在切入點(diǎn)前的操作,按order的值由小到大執(zhí)行
在切入點(diǎn)后的操作,按order的值由大到小執(zhí)行

延伸:

有看官可能會(huì)問(wèn),如果我要打印請(qǐng)求從進(jìn)來(lái),到結(jié)束,所需要的時(shí)間,定義一個(gè)成員變量,用來(lái)統(tǒng)計(jì)時(shí)間,同時(shí)給@Before跟@AfterReturning訪問(wèn),可能會(huì)有同步的問(wèn)題,所以我們引用一個(gè)ThreadLocal指定泛型的對(duì)象,在@Before記錄請(qǐng)求的時(shí)間,在@AfterReturning扣除記錄的時(shí)間,就是消耗的時(shí)間,代碼如下:

/**
 * 項(xiàng)目名:SpringBootDemo
 * 創(chuàng)建人:賀小五
 * 創(chuàng)建時(shí)間:16/12/4 下午7:05
 * 類名:AspectDemo
 * 類描述:
 */
//申明是個(gè)切面
@Aspect
//申明是個(gè)spring管理的bean
@Component
@Order(1)
public class AspectDemo {
  private Logger log = Logger.getLogger(getClass());
  private Gson gson = new Gson();
  ThreadLocal<Long> startTime = new ThreadLocal<Long>();
  //申明一個(gè)切點(diǎn) 里面是 execution表達(dá)式
  @Pointcut("execution(public * com.example.DemoApplication.*(..))")
  private void controllerAspect() {
  }
  //請(qǐng)求method前打印內(nèi)容
  @Before(value = "controllerAspect()")
  public void methodBefore(JoinPoint joinPoint) {
   startTime.set(System.currentTimeMillis());
   ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
   HttpServletRequest request = requestAttributes.getRequest();
   //打印請(qǐng)求內(nèi)容
   log.info("===============請(qǐng)求內(nèi)容===============");
   log.info("請(qǐng)求地址:" + request.getRequestURL().toString());
   log.info("請(qǐng)求方式:" + request.getMethod());
   log.info("請(qǐng)求類方法:" + joinPoint.getSignature());
   log.info("請(qǐng)求類方法參數(shù):" + Arrays.toString(joinPoint.getArgs()));
   log.info("===============請(qǐng)求內(nèi)容===============");
  }
  //在方法執(zhí)行完結(jié)后打印返回內(nèi)容
  @AfterReturning(returning = "o", pointcut = "controllerAspect()")
  public void methodAfterReturing(Object o) {
   log.info("--------------返回內(nèi)容----------------");
   log.info("Response內(nèi)容:" + gson.toJson(o));
   log.info("--------------返回內(nèi)容----------------");
   log.info("請(qǐng)求處理時(shí)間為:"+(System.currentTimeMillis() - startTime.get()));
  }
}

以上,均為本人測(cè)試而得出的結(jié)果,可能會(huì)有出入,或者錯(cuò)誤,歡迎指正.

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • java DateUtil工具類時(shí)間戳類型轉(zhuǎn)換詳解

    java DateUtil工具類時(shí)間戳類型轉(zhuǎn)換詳解

    這篇文章主要為大家詳細(xì)介紹了java DateUtil工具類時(shí)間戳類型轉(zhuǎn)換的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • Java數(shù)據(jù)結(jié)構(gòu)和算法之冒泡排序(動(dòng)力節(jié)點(diǎn)Java學(xué)院整理)

    Java數(shù)據(jù)結(jié)構(gòu)和算法之冒泡排序(動(dòng)力節(jié)點(diǎn)Java學(xué)院整理)

    冒泡排序(Bubble Sort)是一種簡(jiǎn)單的排序算法。本文重點(diǎn)給大家介紹java數(shù)據(jù)結(jié)構(gòu)和算法之冒泡排序,非常不錯(cuò),具有參考借鑒價(jià)值,需要的的朋友參考下吧
    2017-04-04
  • Spring Boot定時(shí)+多線程執(zhí)行過(guò)程解析

    Spring Boot定時(shí)+多線程執(zhí)行過(guò)程解析

    這篇文章主要介紹了Spring Boot定時(shí)+多線程執(zhí)行過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-01-01
  • 使用springboot自動(dòng)配置源碼解讀

    使用springboot自動(dòng)配置源碼解讀

    自動(dòng)裝配是Spring Boot的一個(gè)核心特性,允許程序員在開發(fā)中更加專注于業(yè)務(wù)邏輯,而不是花費(fèi)大量的時(shí)間去配置和管理第三方組件,當(dāng)開發(fā)者在pom.xml文件中添加了某個(gè)依賴后,Spring Boot通過(guò)自動(dòng)配置的方式,將這些第三方組件的實(shí)例自動(dòng)注入到IOC容器中
    2024-11-11
  • MyBatis如何使用(三)

    MyBatis如何使用(三)

    這篇文章主要介紹了MyBatis如何使用(三)的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-07-07
  • Java日期操作方法工具類實(shí)例【包含日期比較大小,相加減,判斷,驗(yàn)證,獲取年份等】

    Java日期操作方法工具類實(shí)例【包含日期比較大小,相加減,判斷,驗(yàn)證,獲取年份等】

    這篇文章主要介紹了Java日期操作方法工具類,結(jié)合完整實(shí)例形式分析了java針對(duì)日期的各種常見操作,包括日期比較大小,相加減,判斷,驗(yàn)證,獲取年份、天數(shù)、星期等,需要的朋友可以參考下
    2017-11-11
  • Java版的7種單例模式寫法示例

    Java版的7種單例模式寫法示例

    這篇文章主要給大家介紹了關(guān)于Java版的7種單例模式寫法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Java具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10
  • Java中的延遲隊(duì)列DelayQueue源碼解析

    Java中的延遲隊(duì)列DelayQueue源碼解析

    這篇文章主要介紹了Java中的延遲隊(duì)列DelayQueue源碼解析,DelayQueue是一個(gè)支持并發(fā)的無(wú)界延遲隊(duì)列,隊(duì)列中的每個(gè)元素都有個(gè)預(yù)定時(shí)間,當(dāng)線程從隊(duì)列獲取元素時(shí),只有到期元素才會(huì)出隊(duì)列,沒有到期元素則阻塞等待,需要的朋友可以參考下
    2023-12-12
  • Java創(chuàng)建線程池為什么一定要用ThreadPoolExecutor

    Java創(chuàng)建線程池為什么一定要用ThreadPoolExecutor

    本文介紹了Java創(chuàng)建線程池為什么一定要用ThreadPoolExecutor,手動(dòng)方式使用ThreadPoolExecutor創(chuàng)建線程池和使用Executors執(zhí)行器自動(dòng)創(chuàng)建線程池,下文更多相關(guān)內(nèi)容需要的小伙伴可以參考一下
    2022-05-05
  • java觀察者模式的三種實(shí)現(xiàn)方式代碼實(shí)例

    java觀察者模式的三種實(shí)現(xiàn)方式代碼實(shí)例

    這篇文章主要介紹了java觀察者模式的三種實(shí)現(xiàn)方式代碼實(shí)例,觀察者模式(又被稱為發(fā)布-訂閱(Publish/Subscribe)模式,屬于行為型模式的一種,它定義了一種一對(duì)多的依賴關(guān)系,讓多個(gè)觀察者對(duì)象同時(shí)監(jiān)聽某一個(gè)主題對(duì)象,需要的朋友可以參考下
    2023-10-10

最新評(píng)論

晋江市| 上栗县| 云霄县| 普格县| 隆林| 鸡泽县| 友谊县| 双辽市| 文安县| 姚安县| 富顺县| 鄱阳县| 文登市| 建宁县| 达拉特旗| 田林县| 内黄县| 阿拉善左旗| 临潭县| 卢湾区| 舟山市| 双牌县| 曲沃县| 临邑县| 昌江| 辽中县| 大渡口区| 阳谷县| 榕江县| 抚松县| 抚州市| 喀喇| 桐庐县| 康定县| 呼和浩特市| 新竹县| 开平市| 江孜县| 临漳县| 多伦县| 岳西县|