spring aop实现log 日志跟踪

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

代码结构

spring aop实现log 日志跟踪_第1张图片

 

 

web.xml


    contextConfigLocation
    
           classpath:spring-application.xml
       

... dispatcher class>org.springframework.web.servlet.DispatcherServletclass> contextConfigLocation classpath:spring-servlet.xml 1 dispatcher /

spring-application.xml

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

 

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


  
    
      
    
  
  
    
      
    
    
     
  

测试输出:

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

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

 

转载于:https://www.cnblogs.com/yaoyuan2/p/10318344.html

你可能感兴趣的:(java,web.xml)