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

相关文章
相关标签/搜索