ConstraintValidator和切面执行顺序

159 阅读1分钟

前言

问了下大模型,说是先进行参数校验,然后再执行切面逻辑;我用公司的框架,也是这个现象;但是用了一下SpringBoot,发现是相反的;

实践

接口

import com.haiwen.springbootsecuritysamples.aop.Auth;
import org.hibernate.validator.constraints.Length;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@Validated
@RestController
public class HelloController {
    @Auth(role = "admin")
    @GetMapping("/hello/{name}")
    @Length(min = 1, max = 10, message = "invalid name")
    public String sayHello(@PathVariable(name = "name") String name) {
        return String.format("hello: %s", name);
    }
}

注解

import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface Auth {
    String role() default "dev";
}

切面

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.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Objects;

@Aspect
@Component
public class AuthAspect {
    @Around("@annotation(Auth)")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        Auth annotation = method.getAnnotation(Auth.class);
        String role = "dev";
        if (Objects.nonNull(annotation)) {
            role = annotation.role();
        }
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
        String authorization = request.getHeader("Authorization");
        if (!role.equals(authorization)) {
            throw new RuntimeException("no authorization");
        }
        return joinPoint.proceed();
    }
}

image.png

先执行了切面逻辑