Springboot自定义注解&传参&简单应用方式
作者:写....写个大西瓜
SpringBoot框架中,通过自定义注解结合AOP可以实现功能如日志记录与耗时统计,首先创建LogController和TimeConsuming注解,并为LogController定义参数,然后,在目标方法上应用这些注解,最后,使用AspectJ的AOP功能,通过切点表达式定位这些注解
Springboot自定义注解&传参&简单应用
1、目录结构
1.1 annotation为自定义注解位置
2、自定义注解
2.1 自定义两个注解LogController、TimeConsuming用来记录日志和统计方法耗时,其中LogController有三个参数
@Target({ElementType.PARAMETER, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface LogController { // 具体操作 String description(); // 日志级别 int logLevel() default LogLevelConstant.INFO; // 日志进程/方法名 String method(); }
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface TimeConsuming { }
3、注解使用
3.1 在需要记录日志和统计方法耗时的方法上使用注解
@PostMapping("/createUser") @LogController(description = "创建用户", method = "/createUser") @TimeConsuming public ResponseEntity<ResponseResultVO> createUser(@Valid @RequestBody SysUsersVo sysUsersVo) { log.info("UserManager = start create user [{}] pwd [{}]", sysUsersVo.getUserName(), sysUsersVo.getUserPwd()); return ResponseEntity.ok(usersService.createUser(sysUsersVo).orElse(ResponseResultVO.builder() .code(ErrorCodeConstant.SYSTEM_ERROR) .msg(ErrorMsgConstant.SYSTEM_ERROR) .build())); }
4、使用Aspect实现功能
4.1 通过Aop以注解作为切点切入方法,实现业务功能
@Pointcut("@annotation(com.pet.annotation.LogController)") public void annotationPoint() { } @Pointcut("@annotation(com.pet.annotation.TimeConsuming)") public void methodTimePoint() { }
4.2 取注解中参数
比如下面方法实现记录日志功能
@Before(value = "annotationPoint() && @annotation(logController)", argNames = "joinPoint, logController") public void beforeController(JoinPoint joinPoint, LogController logController) { HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest(); HttpSession session = request.getSession(); SysUsers user = (SysUsers) session.getAttribute(HttpConstant.SESSION_USER); String realMethodName = joinPoint.getSignature().getName(); log.info("Aspect = [{}] ,user [{}] , method [{}] , logLevel [{}] , do [{}] , realMethod [{}]", new Date(), user == null ? "system" : user.getUserName(), logController.method(), logController.logLevel(), logController.description(), realMethodName); // 异步处理日志 publisher.publishEvent(new LogToDbEvent( LogToDbEventEntity.builder() .date(new Date()) .userName(user == null ? "system" : user.getUserName()) .method(logController.method()) .logLevel(logController.logLevel()) .description(logController.description()) .realMethod(realMethodName) .build())); }
统计方法耗时方法
@Around(value = "methodTimePoint()") public Object apiTimeConsuming(ProceedingJoinPoint pjp) throws Throwable { long begin = System.currentTimeMillis(); String method = pjp.getSignature().getName(); String className = pjp.getTarget().getClass().getName(); Object ret = pjp.proceed(); log.info("Aspect = [{}] ,class [{}] , method [{}] , time consuming[{}]", new Date(), className, method, System.currentTimeMillis() - begin); return ret; }
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。