`
y806839048
  • 浏览: 1083166 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

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

    博客分类:
  • log
log 
阅读更多

 

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

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

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics