欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

加入切面环绕通知实现,日志比较完善的使用方式

程序员文章站 2023-12-22 08:58:04
...

 

加入切面环绕通知实现,日志比较完善的使用方式

1,配置好相应的日志框架,在需要的地方手动打日志(消费端,服务端都如此配置)

 

 

 1、添加依赖包logback使用需要和slf4j一起使用,所以总共需要添加依赖的包有slf4j-api

logback使用需要和slf4j一起使用,所以总共需要添加依赖的包有slf4j-api.jar,logback-core.jar,logback-classic.jar,logback-access.jar这个暂时用不到所以不添加依赖了,maven配置

  <properties>

    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

    <logback.version>1.1.7</logback.version>

    <slf4j.version>1.7.21</slf4j.version>

  </properties>

 

  <dependencies>

    <dependency>

      <groupId>org.slf4j</groupId>

      <artifactId>slf4j-api</artifactId>

      <version>${slf4j.version}</version>

      <scope>compile</scope>

    </dependency>

    <dependency>

      <groupId>ch.qos.logback</groupId>

      <artifactId>logback-core</artifactId>

      <version>${logback.version}</version>

    </dependency>

    <dependency>

      <groupId>ch.qos.logback</groupId>

      <artifactId>logback-classic</artifactId>

      <version>${logback.version}</version>

      </dependency>

  </dependencies>

 

  2、logback.xml配置

<?xml version="1.0" encoding="UTF-8"?>

<configuration debug="false">

<!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->

<property name="LOG_HOME" value="/home" />

<!-- 控制台输出 -->

<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">

<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">

<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->

<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>

</encoder>

</appender>

<!-- 按照每天生成日志文件 -->

<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">

<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">

<!--日志文件输出的文件名-->

<FileNamePattern>${LOG_HOME}/TestWeb.log.%d{yyyy-MM-dd}.log</FileNamePattern>

<!--日志文件保留天数-->

<MaxHistory>30</MaxHistory>

</rollingPolicy>

<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">

<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->

<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>

</encoder>

<!--日志文件最大的大小-->

<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">

<MaxFileSize>10MB</MaxFileSize>

</triggeringPolicy>

</appender>

 

<!-- 日志输出级别 -->

<root level="INFO">

<appender-ref ref="STDOUT" />

</root>

</configuration>

 

  3、java代码

  /**

  * Hello world!

  */

  public class App {

 

  private final static Logger logger = LoggerFactory.getLogger(App.class);

 

    public static void main(String[] args) {

      logger.info("logback 成功了");

      logger.error("logback 成功了");

      logger.debug("logback 成功了");

    }

  }

 

 

参考:

https://www.cnblogs.com/warking/p/5710303.html

 

2,在1的基础上,配置切面---》利用切面,环绕通知,自动拦截,

一般用来打印请求,参数,返回结果(不是拦截器)

这种可以弥补1中设点不够的问题,让临时调试不需要不断点

 

这个LogAopAspect就是切面,在这里将通知植入定义好的切点

@Component将类纳入spring,@Aspect注解定义切面,需要定义xml启动注解的扫描

@Pointcut定义切点(程序正常方法)

@Around 定义通知,这里通知植入切点(通知修饰的方法)

 

 

 

消费端:

 

 

package com.houbank.incoming.web.interceptor;

 

import java.util.HashMap;

import java.util.Map;

 

import javax.servlet.http.HttpServletRequest;

 

import org.aspectj.lang.ProceedingJoinPoint;

import org.aspectj.lang.annotation.Around;

import org.aspectj.lang.annotation.Aspect;

import org.aspectj.lang.annotation.Pointcut;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Component;

 

import com.alibaba.druid.support.spring.mvc.StatHandlerInterceptor;

import com.alibaba.fastjson.JSON;

 

/**

 * 

 * <p>自定义日志拦截类</p>

 * @author houzhanshan

 * @version $Id: LogAopAspect.java, v 0.1 2017年6月5日 上午10:08:19  Exp $

 */

@Component

@Aspect

public class LogAopAspect {

 

    public static final String REQUESTIP     = "requestIp";

 

    public static final String REQUESTPORT   = "requestPort";

 

    public static final String REQUESTURI    = "requestUri";

 

    public static final String REQUESTTYPE   = "requestType";

 

    public static final String REQUEST_PARAM = "param";

 

    @Pointcut("execution(* com.houbank.incoming.web.controller..*(..)) and  @within(org.springframework.web.bind.annotation.Controller)")

    private void anyAcesssAndResponseMethdod() {

    }

 

    @Autowired

    private HttpServletRequest request;

 

    @Around("anyAcesssAndResponseMethdod()")

    public Object notifyLog(ProceedingJoinPoint joinPoint) throws Throwable {

        Object returnObj = null;

        if (joinPoint.getArgs().length > 0) {

            Map<String, Object> paramMap = new HashMap<>();

            paramMap.put(REQUESTIP, request.getServerName());

            paramMap.put(REQUESTPORT, String.valueOf(request.getServerPort()));

            paramMap.put(REQUESTURI, request.getRequestURI());

            paramMap.put(REQUESTTYPE, request.getMethod());

            paramMap.put(REQUEST_PARAM, JSON.toJSONString(request.getParameterMap()));

            LogUtils.accessLog.info("请求request" + JSON.toJSONString(paramMap));

            returnObj = joinPoint.proceed();//植入的切点

            if (returnObj != null) {

                LogUtils.accessLog.info("返回response" + JSON.toJSONString(returnObj));

            }

            return returnObj;

 

        } else {

            Map<String, Object> paramMap = new HashMap<>();

            paramMap.put(REQUESTIP, request.getServerName());

            paramMap.put(REQUESTPORT, String.valueOf(request.getServerPort()));

            paramMap.put(REQUESTURI, request.getRequestURI());

            paramMap.put(REQUESTTYPE, request.getMethod());

            LogUtils.accessLog.info("返回request" + JSON.toJSONString(paramMap));

            returnObj = joinPoint.proceed();

            if (returnObj != null) {

                LogUtils.accessLog.info("返回response" + JSON.toJSONString(returnObj));

            }

 

        }

        return returnObj;

 

    }

    

    

    static class AccessLog {

        private static Logger logger;

            

            public static Logger getLogger(String name) {

                logger = LoggerFactory.getLogger(name);

                return logger;

            }

        }

 

}

 

 

xml

 

配置切面注解扫描:

 

<?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.xsd

           http://www.springframework.org/schema/aop

           http://www.springframework.org/schema/aop/spring-aop.xsd">

 

    <!-- 拦截器 --><!-- 启动对@AspectJ注解的支持  -->

    <aop:aspectj-autoproxy/>

    

</beans>

 

 

 

 

 

 

服务端:

 

@Component纳入spring管理,@Aspect定义切面,xml需配置切面的扫描

@Pointcut定义切点

@Before 前置通知,@AfterReturning后置通知

 

 

 

 

 

 

 

package com.houbank.incoming.service.log;

 

import java.lang.reflect.Method;

 

import org.aspectj.lang.JoinPoint;

import org.aspectj.lang.annotation.AfterReturning;

import org.aspectj.lang.annotation.Aspect;

import org.aspectj.lang.annotation.Before;

import org.aspectj.lang.annotation.Pointcut;

import org.aspectj.lang.reflect.MethodSignature;

import org.springframework.stereotype.Component;

 

import lombok.extern.slf4j.Slf4j;

 

@Aspect

@Component

@Slf4j

public class LogAspect {

 

@Pointcut("execution(* com.houbank.incoming.service.impl.*.*(..))")  

    public void methodPointcut() {}

 

@Before("methodPointcut()")

    public void before(JoinPoint joinPoint) {

        Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();

        //查询不记录日志

        if(method.getName().startsWith("select") || method.getName().startsWith("get") || method.getName().startsWith("query")) {

        return;

        }

        StringBuilder sb = new StringBuilder();

        sb.append(method.getDeclaringClass().getSimpleName()).append(".").append(method.getName()).append(" req:");

        for(int i = 0; i < joinPoint.getArgs().length; i++) {

        sb.append(joinPoint.getArgs()[i]);

        }

        log.info(sb.toString());

    }

 

@AfterReturning(returning="rvt", pointcut="methodPointcut()")

    public void after(JoinPoint joinPoint, Object rvt) {

        Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();

        //查询不记录日志

        if(method.getName().startsWith("select") || method.getName().startsWith("get") || method.getName().startsWith("query")) {

        return;

        }

        log.info(method.getDeclaringClass().getSimpleName() + "."+ method.getName() + " resp:" + rvt);

    }

}

 

 

 

 

 

 

 

 

 

 

 

xml配置:

 

<!-- 启动对@AspectJ注解的支持  -->

    <aop:aspectj-autoproxy proxy-target-class="true"/>

 

相关标签: log

上一篇:

下一篇: