spring aop 日志攔截器的實現(原創)


spring aop 日志攔截器的實現(原創)

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

具體實現

引入相關切面依賴

     <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。

 

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();
         }
      }
   }
}

日志攔截器的配置

配置攔截器,配置切面作用的范圍的表達式

<?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)。

核心概念

  • 橫切關注點

    對那些方法繼續攔截,攔截后怎么處理,這些關注點稱之為橫切關注點

  • 切面(aspect)

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

  • 連接點(joinpoint)

    被攔截到的點,因為Spring只支持方法類型的連接點,所以在Spring中連接點指的就是被攔截到的方法,實際上連接點還可以是字段或者構造器

  • 切入點(pointcut)

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

  • 通知(advice)

    所謂通知指的就是指攔截到連接點之后要執行的代碼,通知分為 前置后置異常最終環繞 通知五類

  • 目標對象

    代理的目標對象

  • 織入(weave)

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

  • 引入(introduction)

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM