zoukankan      html  css  js  c++  java
  • spring aop实现log 日志跟踪

    之前写的那篇是基于springboot的(https://www.cnblogs.com/yaoyuan2/p/10302802.html),由于遗留项目用的是spring,因此需要在spring基础上实现。

    代码结构

    web.xml

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
               classpath:spring-application.xml
           </param-value>
    </context-param>
    ... <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- <init-param> <param-name>contextClass</param-name> <param-value> org.springframework.web.context.support.AnnotationConfigWebApplicationContext </param-value> </init-param> --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-servlet.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>

    spring-application.xml

    <context:component-scan base-package="com.ebc.config" />

    因为下边com.ebc.config.LogAspectConfig用到了

    @Aspect
    @Component

    所以,为了扫描到才加以上

    spring-servlet.xml

    <beans 
      ...
        xmlns:aop="http://www.springframework.org/schema/aop"
        
         http://www.springframework.org/schema/aop 
         http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
         ">
    <!-- 启动对@AspectJ注解的支持 -->  
    <aop:aspectj-autoproxy/>

    com.ebc.config.LogAspectConfig

    package com.ebc.config;
    
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.annotation.After;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.aspectj.lang.annotation.Pointcut;
    import org.slf4j.MDC;
    import org.springframework.stereotype.Component;
    
    import cn.hutool.core.util.IdUtil;
    
    @Aspect
    @Component
    public class LogAspectConfig {
        /**
         * 第1个* 方法属性 public/private/....
         * 接着,连着的2个*,包
         * 然后的1个*,类
         * 最后1个*,方法
         * (..)方法里的参数。..标示任意参数
         */
        @Pointcut("execution(* com.ebc.**.*.*(..))")
        public void methodCut(){}
        /**
         * 方法调用之前调用
         */
        @Before("methodCut()")
        public void doBefore(JoinPoint joinPoint) throws InterruptedException{
            String requestId = String.valueOf(IdUtil.objectId());
            MDC.put("requestId",requestId);
        }
    
        /**
         * 方法之后调用
         */
        @After("methodCut()")
        public void doAfter(JoinPoint joinPoint) {
            MDC.clear();
        }
    
    }

    log4j2.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <Configuration>
      <Appenders>
        <CONSOLE name="CONSOLE">
          <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{requestId}] %-5level | %C.%M:%L - %m%n"/>
        </CONSOLE>
      </Appenders>
      <Loggers>
        <Root level="ERROR">
          <AppenderRef ref="CONSOLE"/>
        </Root>
        <logger name="com.ebc.web" level="INFO" />
         <logger name="com.ebc.disruptor" level="INFO" />
      </Loggers>
    </Configuration>

    测试输出:

    2019-01-25 10:29:10.609 [5c4a7476cbb0db4b262e20cf] INFO  | com.ebc.web.IndexController.index:25 - 接收参数:name=遥远2,minernum=222
    一月 25, 2019 10:29:10 上午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
    信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@105fac24: startup date [Fri Jan 25 10:29:10 GMT+08:00 2019]; root of context hierarchy
    2019-01-25 10:29:10.625 [5c4a7476cbb0db4b262e20cf] INFO  | com.ebc.disruptor.UserMinerProducer.publish:16 - 接收:5c4a7476cbb0db4b262e20cf,222
    2019-01-25 10:29:10.635 [] INFO  | com.ebc.disruptor.UserMinerHandler.onEvent:18 - userName=5c4a7476cbb0db4b262e20cf,amount=222

    mdc的本质采用ThreadLocal,一个线程(含子线程)内共享变量。

    而现在的项目用的是disruptor,跨主线程,因此在UserMinerHandler(消费端)无法获取到共享变量。采用了一个变通的方法,就是业务代码传递过去。所以,userName里才填充了MDC的值。

    如果有好的方法,欢迎留言。

  • 相关阅读:
    java final计算
    浅析Java中的final关键字
    easyui
    Java:类与继承
    java中&和&&
    XML
    JSON
    SQL
    selenium
    Metasploit
  • 原文地址:https://www.cnblogs.com/yaoyuan2/p/10318344.html
Copyright © 2011-2022 走看看