filter、interceptor、controllerAdvice、aspect执行顺序

一、filter、interceptor、controllerAdevice、aspect
1、filter,这是java的过滤器,和框架无关的,是所有过滤组件中最外层的,从粒度来说是最大的。

配置方式,有直接实现Filter+@component,@Bean+@configuration(第三方的filter)

2、interceptor,spring框架的拦截器

配置方式,@configuration+继承WebMvcConfigurerAdapter或WebMvcConfigurationSupport类添加过滤器。

继承WebMvcConfigurationSupport不需要声明@EnableWebMvc注解,继承WebMvcConfigurerAdapter需要 @see org.springframework.web.servlet.config.annotation.EnableWebMvc
@RestController的类和带@ResponseBody的方法在被调用后response会直接写入输出流,在postHandle和afterCompletion这两个方法执行之前就已经把数据返回,导致这两个方法里面的response根本获取不到响应数据

拦截器可以分为两种类型:
一是WebMVC:负责拦截请求,类似于过滤器,对用户的请求在Controller接收前进行处理,在Controller处理完成后加工结果等。使用时需实现HandlerInterceptor接口。
二是AOP:拦截指定类型的方法,通过动态代理模式实现,可以在方法的调用前和调用后添加功能处理。使用时需要实现MethodInterceptor接口。

实现MethodInterceptor拦截器大致也分为两种:
一种是实现MethodInterceptor接口
另一种利用Aspect的注解或配置。

3、aspect,可以自定义要切入的类甚至再细的方法,粒度最小。加个注解用效果更佳。

4、controllerAdvice,是controller的增强,和ExceptionHandler一起用来做全局异常。也可以配合ResponseBodyAdvice接口来对@ResponseBody的返回数据进行加工再返回(同理还有RequestBodyAdvice-> @RequestBody等)


上图给出了filter、interceptor、controllerAdvice、aspect、controller执行顺序,即请求接入的时候,请求会先到达filter -> interceptor -> controllerAdvice -> aspect -> controller

二、每一类有多个时的执行顺序

多个filter内部如何控制执行顺序呢
使用或者Order接口
1.web.xml配置: 谁定义在上边,谁先执行
2.Order注解配置:Order(1)、Order(2) ,值小的先执行
3.Ordered接口

多个interceptor内部如何控制执行顺序呢
1.每个Interceptor 的调用会依据它的声明顺序依次执行
如以下例子:

@Configuration
public class WebAppConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        super.addInterceptors(registry);
        //请求拦截
        registry.addInterceptor(new MyInterceptor2()).addPathPatterns("/**").excludePathPatterns("/loginfrom","/login");
        registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**").excludePathPatterns("/loginfrom","/login");
    }
}

2.使用InterceptorRegistrationd的Order方法,值小的先执行

@Configuration
public class WebAppConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        super.addInterceptors(registry);
        //请求拦截
        registry.addInterceptor(new MyInterceptor2()).order(50).addPathPatterns("/**").excludePathPatterns("/loginfrom","/login");
        registry.addInterceptor(new MyInterceptor()).order(10).addPathPatterns("/**").excludePathPatterns("/loginfrom","/login");
    }
}

多个controllerAdvice内部如何控制执行顺序呢
1.Order注解配置:Order(1)、Order(2) ,值小的先执行
2.Ordered接口

多个aspect内部如何控制执行顺序呢
1.Order注解配置:Order(1)、Order(2) ,值小的先执行
2.Ordered接口

注:
RequestBodyAdvice:在 sping 4.2 新加入的一个接口,它可以使用在 @RequestBody 修改的参数之前进行参数的处理,比如进行参数的解密。

ResponseBodyAdvice:在 spring 4.1 新加入的一个接口,在消息体被HttpMessageConverter写入之前允许 Controller 中 @ResponseBody 修饰的方法调整响应中的内容,比如进行相应的加密。

SpringBoot 中可以利用@RequestBody这样的注解完成请求内容体与对象的转换。而RequestBodyAdvice 则可用于在请求内容对象转换的前后时刻进行拦截处理,其定义了几个方法:
supports:判断是否支持handleEmptyBody,当请求体为空时调用
beforeBodyRead:在请求体未读取(转换)时调用
afterBodyRead:在请求体完成读取后调用

SpringMVC对出参和入参有非常友好的拓展支持,方便你对数据的输入和输出有更大的执行权,我们如何通过SpringMVC定义的结果做一系列处理呢?

RequestBodyAdvice:
入参,针对所有以@RequestBody的参数做处理
ResponseBodyAdvice:
出参,针对所有以@ResponseBody的参数做处理

  • 4
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值