자바 주 해 는 aspectj AOP 와 결합 하여 로그 인쇄 작업 을 진행 합 니 다.

많은 시스템 개발 에서 우 리 는 지 정 된 방법 이 호출 되 기 전이 나 그 후에 이 방법의 호출 시간 과 방법의 출 참 과 입 참 을 인쇄 할 수 있 기 를 희망 합 니 다.spring 의 AOP 를 사용 할 수 있 고 사용자 정의 주해 와 결합 하여 지 정 된 매개 변 수 를 인쇄 할 수 있 습 니 다.
예 를 들 면:
층 을 나 누 는 구조 시스템 은 층 마다 지 정 된 시스템 이름 이 있 고 모든 방법 은 자신 이 지정 한 역할 을 합 니 다(주 해 를 통 해 지정 하고 절단면 에서 이 매개 변 수 를 추출 합 니 다).또한 주 해 를 지정 한 로그 형식(주해 에서 지정 하고 절단면 에서 파 라 메 터 를 꺼 내 판단 한 다음 에 해당 하 는 로그 형식 을 인쇄 할 수 있 습 니 다).
1.먼저 사용자 정의 주석 이 필요 합 니 다.
시스템 이름:이 시스템 의 이름 을 표시 합 니 다.
bizCode:구체 적 인 방법 설명 표시
로그 형식

package myspring;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface LogAnnotation {
 String systemName();
 String bizCode();
 LogType logtype() default LogType.TIME;
}
2.정의 로그 형식 매 거 진:

package myspring;
public enum LogType {
 TIME("TIME", "      "),
 PARAM("PARAM", "    ");
 private String type;
 private String desc;
 LogType(String type, String desc) {
  this.type = type;
  this.desc = desc;
 }
 public String getType() {
  return type;
 }
 public void setType(String type) {
  this.type = type;
 }
 public String getDesc() {
  return desc;
 }
 public void setDesc(String desc) {
  this.desc = desc;
 }
}
3.절단면 코드:
그 중 execution(**(..)
첫 번 째*:모든 반환 값 표시
두 번 째*:모든 가방 일치 규칙 과 모든 클래스 일치 규칙 및 모든 방법 일치 규칙 을 표시 합 니 다.
두 점...:매개 변수 가 일치 하 는 것 을 표시 합 니 다.
예 를 들 면:

execution(* *..*Service.*(..))
서비스 로 끝 나 는 모든 패키지 의 클래스 나 클래스 를 되 돌려 주 는 모든 방법 을 표시 합 니 다.
*..:모든 가방
*:Service 는 Service 로 끝 나 는 모든 클래스 또는 실현 클래스 를 표시 합 니 다.

execution(* cn.lijie.MyService.*(..))
반환 값 cn.lijie 패키지 아래 MyService 클래스 또는 구현 클래스 의 모든 방법 을 나타 내 는 모든 매개 변수
코드 는 다음 과 같 습 니 다:

package myspring;
import com.alibaba.fastjson.JSON;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;
import org.springframework.util.StringUtils;
@Component
@Aspect
public class LogAspect {
 private static Logger thisLog = LoggerFactory.getLogger(LogAspect.class);
 private static Logger timeLog = LoggerFactory.getLogger(TimeTypeLog.class);
 private static Logger paramLog = LoggerFactory.getLogger(ParamTypeLog.class);
 @Around("execution(* *(..)) && @annotation(logAnnotation)")
 public Object log(ProceedingJoinPoint point, LogAnnotation logAnnotation) {
  StopWatch stop = new StopWatch();
  stop.start();
  boolean flag = false;
  Object retValue = null;
  try {
   retValue = point.proceed();
   flag = true;
  } catch (Throwable throwable) {
   throwable.printStackTrace();
  } finally {
   stop.stop();
   if (logAnnotation.logtype().equals(LogType.TIME)) {
    timeLog(this.getMethod(point), point, stop.getTotalTimeMillis(), logAnnotation, flag);
   } else {
    paramLog(this.getMethod(point), point, retValue);
   }
  }
  return retValue;
 }
 private void timeLog(String method, ProceedingJoinPoint point, long totalTimeMillis, LogAnnotation logAnnotation, boolean flag) {
  timeLog.info("   :{},       :{},      :{},     :{}ms", logAnnotation.systemName(), method, flag, totalTimeMillis);
 }
 private void paramLog(String method, ProceedingJoinPoint point, Object retValue) {
  try {
   String result = JSON.toJSONString(retValue);
   //    
   Object[] args = point.getArgs();
   StringBuffer sb = new StringBuffer();
   for (Object obj : args) {
    String str = JSON.toJSONString(obj);
    sb.append(subStr(str, 200)).append(" ");
   }
   paramLog.info("     :{},   :{},   :{}", method, sb, subStr(result, 200));
  } catch (Exception e) {
   thisLog.warn("             ,    :{}", e.getMessage());
  }
 }
 private String getMethod(ProceedingJoinPoint pjp) {
  MethodSignature methodSignature = (MethodSignature) pjp.getSignature();
  return methodSignature.getDeclaringTypeName() + "#" + methodSignature.getMethod().getName();
 }
 private String subStr(String string, int length) {
  if (!StringUtils.isEmpty(string)) {
   if (string.length() > length) {
    string = string.substring(0, 200);
    return string;
   }
  }
  return string;
 }
}
4.작업 대상 정의:

package myspring;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Component("logTest")
public class LogTest {
 private static Logger logger = LoggerFactory.getLogger(LogTest.class);
 @LogAnnotation(systemName = "     ", bizCode = "+", logtype = LogType.TIME)
 public int testLog01(int a, int b) {
  logger.info("  +  ");
  return a + b;
 }
 @LogAnnotation(systemName = "     ", bizCode = "-", logtype = LogType.PARAM)
 public int testLog02(int a, int b) {
  logger.info("  -  ");
  return a - b;
 }
}
5.서로 다른 종류의 로 그 를 구분 하 는 데 사용 할 빈 클래스 두 개 를 정의 합 니 다.

package myspring;
public class TimeTypeLog {

package myspring;
public class ParamTypeLog {
}
6.spring xml 프로필:

<context:component-scan base-package="myspring"/>
<aop:aspectj-autoproxy/>
7.spring 을 시작 하 는 테스트 클래스:

package myspring;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main {
 public static void main(String[] args) {
  AbstractApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
  LogTest logTest = (LogTest) context.getBean("logTest");
  logTest.testLog01(1, 2);
  logTest.testLog02(3, 4);
  context.registerShutdownHook();
 }
}
8.pom

<properties>
  <spring_version>4.3.8.RELEASE</spring_version>
 </properties>
 <dependencies>
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-context</artifactId>
   <version>${spring_version}</version>
  </dependency>
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-core</artifactId>
   <version>${spring_version}</version>
  </dependency>
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-beans</artifactId>
   <version>${spring_version}</version>
  </dependency>
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-aop</artifactId>
   <version>${spring_version}</version>
  </dependency>
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-test</artifactId>
   <version>${spring_version}</version>
  </dependency>
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-aop</artifactId>
   <version>${spring_version}</version>
  </dependency>
  <dependency>
   <groupId>org.aspectj</groupId>
   <artifactId>aspectjrt</artifactId>
   <version>1.8.11</version>
  </dependency>
  <dependency>
   <groupId>org.aspectj</groupId>
   <artifactId>aspectjweaver</artifactId>
   <version>1.8.11</version>
  </dependency>
  <dependency>
   <groupId>org.slf4j</groupId>
   <artifactId>slf4j-api</artifactId>
   <version>1.7.21</version>
  </dependency>
  <dependency>
   <groupId>ch.qos.logback</groupId>
   <artifactId>logback-classic</artifactId>
   <version>1.1.7</version>
  </dependency>
  <dependency>
   <groupId>ch.qos.logback</groupId>
   <artifactId>logback-core</artifactId>
   <version>1.1.7</version>
  </dependency>
  <dependency>
   <groupId>com.alibaba</groupId>
   <artifactId>fastjson</artifactId>
   <version>1.2.4</version>
  </dependency>
 </dependencies>
마지막 으로 테스트 를 수행 하 는 클래스 입 니 다.로 그 는 다음 과 같 습 니 다.

보충:spring boot 사용자 정의 주석 자동 인쇄 방법 로그(입력 및 반환 값)
pom 파일

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>2.1.4.RELEASE</version>
  <relativePath/> <!-- lookup parent from repository -->
 </parent>
 <groupId>com.aline</groupId>
 <artifactId>demo</artifactId>
 <version>0.0.1-SNAPSHOT</version>
 <name>demo</name>
 <description>Demo project for Spring Boot</description>
 <properties>
  <java.version>1.8</java.version>
 </properties>
 <dependencies>
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-aop</artifactId>
  </dependency>
  <dependency>
   <groupId>com.alibaba</groupId>
   <artifactId>fastjson</artifactId>
   <version>1.2.7</version>
  </dependency>
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-test</artifactId>
   <scope>test</scope>
  </dependency>
 </dependencies>
 <build>
  <plugins>
   <plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
   </plugin>
  </plugins>
 </build>
</project>
로그 설명 정의
SysLog.java

package com.aline.demo.annotation;
import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SysLog {
}
로그 인 스 턴 스 캐 시 정의

LoggerCache.class
package com.aline.demo.util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashMap;
public class LoggerCache {
 /**
  *           
  */
 private static HashMap<String, Logger> LOGERS = new HashMap<String, Logger>();
 /**
  *              
  * @param className       this.getClass().getName();
  * @return
  */
 public static Logger getLoggerByClassName(String className) {
  //    map       
  Logger logger = LOGERS.get(className);
  //      
  if (logger == null) {
   //         
   logger = LoggerFactory.getLogger(className);
   //      map 
   LOGERS.put(className, logger);
  }
  //   
  return logger;
 }
}
로그 기록 을 실현 하기 위해 절단면 을 정의 합 니 다.
SysLogAspect.java

package com.aline.demo.aspect;
import com.alibaba.fastjson.JSON;
import com.aline.demo.util.LoggerCache;
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.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
@Aspect
@Component
public class SysLogAspect {
 @Pointcut("@annotation(com.aline.demo.annotation.SysLog)")
 public void log() {
 }
 /**
  *             
  *
  * @param joinPoint
  * @return
  * @throws Throwable
  */
 @Around(value = "log()")
 public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
  //            (     )
  String className = joinPoint.getTarget().getClass().getName();
  //        
  MethodSignature signature = (MethodSignature) joinPoint.getSignature();
  Method method = signature.getMethod();
  //           
  Logger log = LoggerCache.getLoggerByClassName(className);
  //     
  log.info(className + "." + method.getName() + "()   ");
  Object[] args = joinPoint.getArgs();
  log.info("Params\t===》\t" + JSON.toJSONString(args));
  //          
  Object proceed = joinPoint.proceed();
  //     
  log.info("Returns\t===》\t" + JSON.toJSONString(proceed));
  //   
  return proceed;
 } 
}
controller 테스트 쓰기
TestController.java

package com.aline.demo.controller;
import com.aline.demo.annotation.SysLog;
import com.aline.demo.util.LoggerCache;
import org.slf4j.Logger;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.text.SimpleDateFormat;
import java.util.Date;
@RestController
@RequestMapping("/test")
public class TestController {
 static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
 @GetMapping("/now")
 public String now(){
  //         
  Logger LOG = LoggerCache.getLoggerByClassName(this.getClass().getName());
  LOG.info("      ==》     。。。");
  return sdf.format(new Date());
 }
 @GetMapping("/hello")
 @SysLog()
 public String hello(String name){
  return "Hello, " + name;
 }
}
방문 하 다.http://localhost:8080/test/hello?name=aline
인쇄 로그:

2019-05-09 16:58:20.410 INFO 40004 --- [nio-8080-exec-1] c.aline.demo.controller.TestController : com.aline.demo.controller.TestController.hello()   ,   ==》
2019-05-09 16:58:20.584 INFO 40004 --- [nio-8080-exec-1] c.aline.demo.controller.TestController : Params ===》 ["aline"]
2019-05-09 16:58:20.598 INFO 40004 --- [nio-8080-exec-1] c.aline.demo.controller.TestController : Returns ===》 "Hello, aline"
방문 하 다.http://localhost:8080/now
인쇄 로그:

2019-05-09 16:58:29.208 INFO 40004 --- [nio-8080-exec-3] c.aline.demo.controller.TestController :       ==》     。。。
이상 은 개인 적 인 경험 이 므 로 여러분 에 게 참고 가 되 기 를 바 랍 니 다.여러분 들 도 저 희 를 많이 응원 해 주시 기 바 랍 니 다.만약 잘못 이 있 거나 완전히 고려 하지 않 은 부분 이 있다 면 아낌없이 가르침 을 주시 기 바 랍 니 다.

좋은 웹페이지 즐겨찾기