切面编程(3):spring拦截器

1 简述

相对于web过滤器,spring 拦截器更接近切面编程,拦截方法不仅可以获取request,response参数,还包含handler参数,通过handler参数可以获取到匹配本次请求controller类的method相关信息,依据该部分信息,可以实施一些更丰富的切面逻辑。

跟spring aop功能很类似,但它只是对http请求做拦截处理。

2. 配置

首先,创建一个实现HandlerInterceptor接口的拦截器类,如下:

@Component
public class DemoInterceptor1 implements HandlerInterceptor {
	
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {		
		System.out.println(String.format("DemoInterceptor1.preHandle, url:%s", request.getRequestURL()));				
		return true;
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
		System.out.println(String.format("DemoInterceptor1.postHandle, url:%s", request.getRequestURL()));		
	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
		System.out.println(String.format("DemoInterceptor1.afterCompletion, url:%s, ex:%s", request.getRequestURL(), ex));
	}
}

然后,注册、配置拦截器,将拦截器与具体http请求url路径关联,支持匹配、排除组合方式配置,如果有多个拦截器,可通过order方法,按从小到大排序,如下:

@Configuration
public class WebConfig implements WebMvcConfigurer {

  @Autowired
  private DemoInterceptor1 demoInterceptor1;
  
  @Autowired
  private DemoInterceptor2 demoInterceptor2;
  
  @Override
  public void addInterceptors(InterceptorRegistry registry) {
      registry.addInterceptor(demoInterceptor1).addPathPatterns("/**").excludePathPatterns("/user/info").order(2);
      registry.addInterceptor(demoInterceptor2).addPathPatterns("/**").excludePathPatterns("/user/info").order(1);
  }
}

3. 功能

spring 拦截器,在功能上跟过滤器很相似,都是对http请求做预处理拦截处理。

下面是http请求大致流量:

在流程上,靠后一些,但仍在具体的Controller相关处理逻辑之前,仍在http输入流ServletInputStream解析之前。

spring 拦截器的优势在于,它属于spring框架,可以充分利用spring提供的资源、比如spring中bean对象注入,通过handler可了解,它由那个Controller的method处理,这方面跟spring aop能力基本是一样的。

相对于Filter而言,spring 拦截器更接近业务,适合与业务有更高的相关度,依此来判断具体采用那种技术的原则之一。

以下是一个简单例子

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {		
		System.out.println(String.format("preHandle, url:%s", request.getRequestURL()));	
		
		if (!this.isPermit(request)) {
			response.setCharacterEncoding(java.nio.charset.StandardCharsets.UTF_8.name());
			response.getWriter().write("请求被拒绝");
			return false;
		}
		
		return true;
	}

4. 对比

4.1 AOP

(1)  跟spring aop基本一样,都提供之前、之后、异常处理能力。

(2)  从处理流程上看,应该是 HandlerInterceptor -> aspect -> controller 处理过程,但二者之间还有HttpMessageConverter等中间处理逻辑,在请求完成阶段,响应结果HttpServletResponse已处理完毕,相对于aspect,对结果的影响已很弱。

4.2 过滤器

(1) 从技术框架来说,web过滤器属于java servlet 原生规范,spring 拦截器属于 spring。因此,拦截器可以很方便的获取IOC容器中的bean,而过滤器不行,或者说比较麻烦(该问题在采用@WebFilter注解后,基本解决)。

(2) 从处理流程看,拦截器靠后些,都是在controller之前,都适合做预处理、拦截等处理。

(3) 从业务相关度来说,spring 拦截器更接近业务,更适合做业务相关的拦截处理,而web过滤器更适合做一些与业务无关的处理逻辑。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值