SpringBoot 请求拦截
- 1 切片(Aspect)
- 1.1 AOP中的相关概念
- 1.2 Advice 的类型
- 2 过滤器(Filter)
- 3 拦截器(Interceptor)
- 3.1 RequestConfig
- 3.2 CustomerInterceptor
在 Spring Boot 中,请求拦截有如下三种方式
切片(Aspect)
过滤器(Filter)
拦截器(Interceptor)
1 切片(Aspect)
1.1 AOP中的相关概念
定义词 |
作用 |
Aspect(切面) |
Aspect 声明类似于 Java 中的类声明,在 Aspect 中会包含着一些 Pointcut 以及相应的 Advice。 |
Joint point(连接点) |
表示在程序中明确定义的点,典型的包括方法调用,对类成员的访问以及异常处理程序块的执行等等,它自身还可以嵌套其它 joint point。 |
Pointcut(切点) |
表示一组 joint point,这些 joint point 或是通过逻辑关系组合起来,或是通过通配、正则表达式等方式集中起来,它定义了相应的 Advice 将要发生的地方。 |
Advice(增强) |
Advice 定义了在 Pointcut 里面定义的程序点具体要做的操作,它通过 before、after 和 around 来区别是在每个 joint point 之前、之后还是代替执行的代码。 |
Target(目标对象) |
织入 Advice 的目标对象.。 |
Weaving(织入) |
将 Aspect 和其他对象连接起来, 并创建 Adviced object 的过程 |
1.2 Advice 的类型
方法 |
作用 |
@Before(“logPointCut()”) |
(前置建议),即在方法执行前 执行前置方法。 |
@AfterReturning(pointcut = “logPointCut()”, returning = “result”) |
(后置建议),即在方法正确执行后 才执行后置方法。 |
@AfterThrowing(“logPointCut()”) |
(后置返回建议),即在方法抛出异常时 执行该后置方法。 |
@After(“logPointCut()”) |
(后置抛出建议),即在方法执行后 执行后置方法。 |
@Around(“logPointCut()”) |
(环绕建议),即在方法执行前后 进行执行前后置方法。 |
@Aspect
@Component
public class CustomerAspect {
@Pointcut("@annotation()")
public void logPointCut() {
}
@Around("logPointCut()")
public Object around(ProceedingJoinPoint point) throws Throwable {
return point.proceed();
}
@Before("logPointCut()")
public void before(JoinPoint point) throws Throwable {
MethodSignature signature = (MethodSignature) point.getSignature();
}
@AfterReturning(pointcut = "logPointCut()", returning = "result")
public void afterReturning(JoinPoint point, Object result) throws Throwable {
MethodSignature signature = (MethodSignature) point.getSignature();
}
}
2 过滤器(Filter)
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;
public class CustomerFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
Filter.super.init(filterConfig);
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
System.out.println("进入 CustomerFilter");
filterChain.doFilter(request, response);
System.out.println("离开 CustomerFilter");
}
@Override
public void destroy() {
Filter.super.destroy();
}
}
3 拦截器(Interceptor)
拦截器相比过滤器,能拿到控制器类和方法,但是依旧无法拿到请求的参数。
方法 |
作用 |
preHandle |
是请求执行前执行。 |
postHandler |
是请求成功执行,如果接口方法抛出异常不会执行,且只有 preHandle 方法返回 true 的时候才会执行。 |
afterCompletion |
是请求结束才执行,无论请求成功或失败都会执行,同样需要 preHandle 返回 true,该方法通常用于清理资源等工作。 |
3.1 RequestConfig
@Configuration
public class RequestConfig extends WebMvcConfigurationSupport {
@Autowired
private CustomerInterceptor interceptor;
@Override
protected void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(interceptor).addPathPatterns("/**");
super.addInterceptors(registry);
}
}
3.2 CustomerInterceptor
@Slf4j
@Component
public class CustomerInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
request.setAttribute("StartTime", System.currentTimeMillis());
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
Long start = (Long) request.getAttribute("StartTime");
log.info("请求执行完毕 总耗时:{}", (System.currentTimeMillis() - start));
}
}