Logging based on Spring AOP and Java annotations

I have written a blog before, using Spring AOP for logging .
In this blog, Spring AOP technology is used to cross-cut all the Controllers in the application, and all requests to access the Controller are logged.
But in real daily production, we may not record all the access, but log some special requests, which requires us to distinguish the entry point of AOP.
We can use Java annotations to distinguish Controllers, and Spring AOP also supports the entry point of annotations.

Build the project environment

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.4.RELEASE</version>
</parent>

<dependencies>
	<!--SpringMVC的启动器依赖-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!--Spring整合junit测试的启动器依赖-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <!--Spring AOP的启动器依赖-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-aop</artifactId>
    </dependency>
    <!--lombck的依赖,用于生产getter和setter方法-->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
    <!--数据库驱动-->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <!--MyBatisPlus的启动器依赖-->
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.0.5</version>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

Create a database log table

CREATE TABLE `log` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `visit_time` datetime DEFAULT NULL,
  `username` varchar(20) DEFAULT NULL,
  `ip` varchar(20) DEFAULT NULL,
  `uri` varchar(50) DEFAULT NULL,
  `method` varchar(100) DEFAULT NULL,
  `execution_time` bigint(20) DEFAULT NULL,
  `exception_name` varchar(50) DEFAULT NULL,
  `exception_message` varchar(20) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8;

Create a log entity class

@Data
@TableName("log")
public class Log {
    @TableId(type = IdType.AUTO)
    private Long id;
    private Date visitTime;
    private String username;
    private String ip;
    private String uri;
    private String method;
    private Long executionTime;
    private String exceptionName;
    private String exceptionMessage;
}

Create logging notes

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LogAnnotation {
}

Controller layer interface writing

  • The interface method of the Controller layer is built on the project environment built by the SpringBoot + MyBatisPlus blog.
@RestController
@RequestMapping("user")
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("page/{currentPage}")
    public ResponseEntity<IPage<User>> findUserByPage(
            @PathVariable("currentPage") Integer currentPage,
            @RequestParam(defaultValue = "5") Integer size) throws Exception {
        return ResponseEntity.ok(userService.findUserByPage(currentPage, size));
    }

    @PostMapping("add")
    public ResponseEntity<Void> saveUser(User user) throws Exception {
        userService.saveUser(user);
        return ResponseEntity.status(HttpStatus.OK).build();
    }

    @LogAnnotation
    @DeleteMapping("{id}")
    public ResponseEntity<Void> delUserById(@PathVariable("id") Integer id) throws Exception {
        userService.delUserById(id);
        return ResponseEntity.status(HttpStatus.OK).build();
    }

	@LogAnnotation
    @PutMapping("update")
    public ResponseEntity<Void> updateUser(User user) throws Exception {
        userService.updateUser(user);
        return ResponseEntity.status(HttpStatus.OK).build();
    }
}

AOP aspect class writing

@Aspect
@Component
public class LogAop {

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private LogDao logDao;

    private Log log;
	
	//切入点中的值使用@annotation,表示这是一个注解切入点,凡是被该注解标识的方法,都会被AOP切入
    @Pointcut("@annotation(com.hrp.annotation.LogAnnotation)")
    public void controllerAOP(){}

    @Before("controllerAOP()")
    public void doBefore(){
        log = new Log();
        log.setVisitTime(new Date());
    }

    @After("controllerAOP()")
    public void doAfter(JoinPoint joinPoint){
        log.setExecutionTime(System.currentTimeMillis() - log.getVisitTime().getTime());
        log.setIp(request.getRemoteAddr());
        log.setUri(request.getRequestURI());
        log.setMethod("[类名]"+joinPoint.getTarget().getClass()+"[方法名]"+joinPoint.getSignature().getName());
    }

    @AfterReturning("controllerAOP()")
    public void doAfterReturning(){
        logDao.insert(log);
    }

    @AfterThrowing(value = "controllerAOP()",throwing = "e")
    public void doException(Exception e){
        log.setExceptionName(e.getClass().getName());
        log.setExceptionMessage(e.getMessage());
        logDao.insert(log);
    }
}

function test

We start the project and access the four paths of the Controller layer. The results are as follows:

RUI Whether to comment Does AOP cut in
/user/page/{currentPage} no no
/user/add no no
/user/{id} Yes Yes
/user/update Yes Yes
Published 85 original articles · praised 92 · views 9212

Guess you like

Origin blog.csdn.net/qq_45193304/article/details/105568902