spring aop 日誌攔截器的實現

利用 spring aop 的 around 來實現日誌攔截器,此攔截器負責打印拋出到頂層的異常日誌。html

具體實現

引入相關切面依賴

<dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.6.9</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.6.9</version>
        </dependency>
        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>2.2</version>
        </dependency>

實現日誌攔截器

攔截異常打印日誌,注意用線程本地變量startLocal,來作一個是否爲第一個(入口)本地方法的標誌。這樣作的目的是爲了不重複在每一個方法裏catch異常, 拋出異常操做的時候打印異常。注意catch的是 java.lang.Throwable級別的異常。包括全部的errors 和 exceptions。java

public class LogInterceptor {
   private final Logger logger = LoggerFactory.getLogger(LogInterceptor.class);

   /**
    * 首次進入標誌
    */
   private static final ThreadLocal<Boolean> startLocal = new ThreadLocal<Boolean>();

   public Object doLog(ProceedingJoinPoint jp) throws Throwable {
      Boolean isStart = startLocal.get();
      // 作源頭標記
      if (isStart == null) {
         startLocal.set(true);
         
         if (logger.isDebugEnabled()) {
            LogUtils.debug(logger, "----------開始進入全局日誌記錄攔截器-------------");
         }
      }

      try {
         // 執行目標方法
         return jp.proceed();
      } catch (Throwable e) {
         if (isStart == null) {
            logger.warn("業務執行出現未知異常:", e);
         }
         
         throw e;
      } finally {
         if (isStart == null) {
            startLocal.remove();
         }
      }
   }
}

日誌攔截器的配置

配置攔截器,配置切面做用的範圍的表達式spring

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
    <aop:aspectj-autoproxy proxy-target-class="true"/>

    <bean id="log_Interceptor" class="com.iplatform.common.interceptor.LogInterceptor"/>
    <aop:config>
        <aop:aspect order="5" id="log_interceptor_aspect" ref="log_Interceptor">
            <aop:pointcut id="log_interceptor_pointcut" expression="execution(* com.tem.*.service..*.*(..)) || execution(* com.tem..*.action.*.*(..)) || execution(* com.tem..*.*Controller.*(..))"/>
            <aop:around method="doLog" pointcut-ref="log_interceptor_pointcut"/>
        </aop:aspect>
    </aop:config>

</beans>

知識點擴展

Spring Aop

AOP(Aspect Oriented Programming)既面向切面編程。解決面向對象編程(OOP)所缺少的橫向邏輯處理的部分。例如每一個方法都須要的對日誌的支持,對事物的處理,對異常的處理等。這種散落在各處的重複邏輯的代碼被稱爲橫切(cross cutting)。AOP剖解開封裝的對象內部,並將那些影響了多個類的公共行爲封裝到一個可重用的模塊,並將其命名爲切面(Aspect)。express

核心概念編程

  • 橫切關注點spa

    對那些方法繼續攔截,攔截後怎麼處理,這些關注點稱之爲橫切關注點線程

  • 切面(aspect)debug

    類是對物理特徵的抽象,切面就是對橫切關注點的抽象代理

  • 鏈接點(joinpoint)日誌

    被攔截到的點,由於Spring只支持方法類型的鏈接點,因此在Spring中鏈接點指的就是被攔截到的方法,實際上鍊接點還能夠是字段或者構造器

  • 切入點(pointcut)

    對鏈接點進行攔截的定義,支持execution 表達式

  • 通知(advice)

    所謂通知指的就是指攔截到鏈接點以後要執行的代碼,通知分爲 前置後置異常最終環繞 通知五類

  • 目標對象

    代理的目標對象

  • 織入(weave)

    將切面應用到目標對象並致使代理對象建立的過程

  • 引入(introduction)

    在不修改代碼的前提下,引入能夠在運行期爲類動態地添加一些方法或字段

文章來源:https://www.cnblogs.com/zhangsdml/p/9772828.html

推薦閱讀:https://www.roncoo.com/article/index?title=spring

相關文章
相關標籤/搜索