Registro basado en anotaciones Spring AOP y Java

He escrito un blog antes, usando Spring AOP para iniciar sesión .
En este blog, la tecnología Spring AOP se utiliza para realizar un corte transversal de todos los Controladores en la aplicación, y todas las solicitudes de acceso al Controlador se registran.
Pero en la producción diaria real, es posible que no registremos todo el acceso, sino que registremos algunas solicitudes especiales, lo que requiere que distingamos el punto de entrada de AOP.
Podemos usar anotaciones de Java para distinguir Controller, y Spring AOP también admite el punto de entrada de las anotaciones.

Construye el entorno del proyecto

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

Crear una tabla de registro de base de datos

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;

Crear una clase de entidad de registro

@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;
}

Crear notas de registro

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

Controlador de escritura de interfaz de capa

  • El método de interfaz de la capa Controlador se basa en el entorno del proyecto creado por el blog SpringBoot + MyBatisPlus .
@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();
    }
}

Escritura de clase de aspecto AOP

@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);
    }
}

Prueba funcional

Comenzamos el proyecto y accedemos a las cuatro rutas de la capa Controlador. Los resultados son los siguientes:

RUI Ya sea para comentar ¿AOP interrumpe?
/ user / page / {currentPage} No No
/ usuario / agregar No No
/ usuario / {id} Si Si
/ usuario / actualización Si Si
Publicado 85 artículos originales · elogiado 92 · vistas 9212

Supongo que te gusta

Origin blog.csdn.net/qq_45193304/article/details/105568902
Recomendado
Clasificación