背景: spring boot + aop,自定义注解收集controller层日志;
- 自定义注解
1.1 自定义注解 pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.5.5</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
</dependency>
</dependencies>
1.2 自定义操作日志注解
import java.lang.annotation.*;
@Target({ElementType.PARAMETER,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface OperLog {
String operModul() default "";
String operType() default "";
String operDesc() default "";
}
1.3 用于打印输出日志的切面
import com.alibaba.fastjson.JSONObject;
import com.dexin.pinyougou.common.vo.ResultVO;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.Objects;
@Aspect
@Component
@Slf4j
public class OperLogAspect {
private Logger logger = LoggerFactory.getLogger(OperLogAspect.class);
@Pointcut("@annotation(com.dexin.pinyougou.common.log.OperLog)")
public void controllerMethod() {
}
@Before(value = "controllerMethod()")
public void LogRequestInfo(JoinPoint joinPoint) throws Throwable {
logger.info("=================================");
HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
StringBuilder requestLog = new StringBuilder();
String methodName = joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
OperLog operlog = signature.getMethod().getAnnotation(OperLog.class);
requestLog.append("请求信息:").append("URL = {").append(request.getRequestURI()).append("},\n")
.append("请求方式 = {").append(request.getMethod()).append("},\n")
.append("请求IP = {").append(request.getRemoteAddr()).append("},\n")
.append("类方法 = {").append(signature.getDeclaringTypeName()).append("}.\n")
.append(signature.getName()).append("},\t").append("}.\n")
.append("操作类型:{").append(operlog.operType()).append("}.\n")
.append(",操作模块:{").append(operlog.operModul()).append("}.\n")
.append(",操作信息{").append(operlog.operDesc());
String[] paramNames = ((MethodSignature) signature).getParameterNames();
Object[] paramValues = joinPoint.getArgs();
int paramLength = null == paramNames ? 0 : paramNames.length;
if (paramLength == 0) {
requestLog.append("请求参数 = {} ");
} else {
requestLog.append("请求参数 = [");
for (int i = 0; i < paramLength - 1; i++) {
requestLog.append(paramNames[i]).append("=").append(JSONObject.toJSONString(paramValues[i])).append(",");
}
requestLog.append(paramNames[paramLength - 1]).append("=").append(JSONObject.toJSONString(paramValues[paramLength - 1])).append("]");
}
logger.info(requestLog.toString());
logger.info("=================================");
}
@AfterReturning(returning = "resultVO", pointcut = "controllerMethod()")
public void logResultVOInfo(ResultVO resultVO) throws Exception {
logger.info("请求结果:" + resultVO.getCode() + "\t" + resultVO.getMsg());
logger.info("============end==================");
}
}
- 将以上java文件打成jar,在另外一个工程引入;
- 在另外一个工程,创建controller
@RestController
@RequestMapping("/brand")
public class BrandController {
@OperLog(operModul = "BrandController",operType = "findAll",operDesc = "返回全部列表")
@GetMapping("/findAll")
public String findAll() {
return "get all success";
}
}
- 创建启动类
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
@MapperScan("com.dexin.sellergoods.dao")
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
@ComponentScan(value = "com.dexin.*")
public class SellerGoodsApplication {
public static void main(String[] args) {
SpringApplication.run(SellerGoodsApplication.class, args);
}
}
-
接口调用日志信息如下 -
注意在启动类上加入扫描@ComponentScan 的作用就是根据定义的扫描路径,把符合扫描规则的类装配到spring容器中;
|