1.前言
拦截器(Interceptor)是一种在软件系统中常见的概念,用于在某个操作执行前或执行后进行干预、处理或记录。在底层实现上,拦截器可以有多种不同的实现方式,具体取决于所使用的编程语言和框架。
在Java开发中,常见的拦截器实现方式是通过AOP(面向切面编程)和动态代理技术来实现。以下是介绍拦截器底层实现的两种常见方式:
动态代理:动态代理是指在运行时创建一个代理对象,用来替代原始对象,并在代理对象中添加额外的逻辑。在拦截器中,可以通过动态代理来创建代理对象,在代理对象的方法执行前后进行拦截并执行相应的操作。Java中的
java.lang.reflect.Proxy
类和CGLIB库提供了动态代理的实现。AOP框架:AOP框架是一种基于切面编程的技术,可以在应用程序运行期间将额外的逻辑织入到目标对象的方法调用中。通过AOP框架,可以定义各种切点和通知类型(如前置通知、后置通知、环绕通知等),并将这些通知织入到目标对象的方法中。常见的Java AOP框架包括Spring AOP和AspectJ。
这两种方式都允许我们在特定的方法或操作执行前后进行拦截,以便进行一些必要的处理,例如日志记录、权限验证、性能监控等。具体选择哪种方式取决于项目需求、技术栈和团队偏好。
2.定义一个项目拦截器
创建一个类实现HandlerInterceptor接口,并重写preHandler(前置)和postHandler(后置)和afterCompletion(完成后)。
以下是示例代码
package com.csy.controller.interceptor;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @Description: 定义一个项目拦截器
* @Author: windStop
* @Date: 2024/5/21 17:09
*/
@Component
public class ProjectInterceptor implements HandlerInterceptor {
@Override
//原始方法调用前执行的内容
//返回值类型可以拦截控制的执行,true放行,false终止
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String contentType = request.getHeader("Content-Type");
HandlerMethod hm = (HandlerMethod)handler;
//可以拿到反射对象
hm.getMethod().invoke(1);
System.out.println("preHandle..."+contentType);
return true;
}
@Override
//原始方法调用后执行的内容
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle...");
}
@Override
//原始方法调用完成后执行的内容
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion...");
}
}
这个
ProjectInterceptor
类实现了HandlerInterceptor
接口,并重写了其中的三个方法:preHandle
、postHandle
和afterCompletion
。下面是对每个方法的详细解释:
preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
:
- 该方法在进入请求处理方法之前被调用。
- 它可以用于进行一些预处理操作,比如身份验证、权限检查等。
- 方法的返回值决定了是否继续执行后续的请求处理,返回
true
表示继续执行,返回false
表示终止请求处理。- 在这个方法中,可以获取到请求的信息,如请求头、参数等,通过
request
对象进行操作。- 参数
handler
是被拦截的处理器方法的反射对象,可以通过它获取更多的信息。
postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
:
- 该方法在请求处理方法执行之后、视图渲染之前被调用。
- 可以对请求处理结果进行后续处理,如修改ModelAndView对象,添加额外的数据等。
- 参数
modelAndView
代表了请求处理方法的返回结果和视图信息。
afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
:
- 该方法在请求完成之后被调用,包括视图渲染完成。
- 无论请求处理过程中是否发生异常,都会执行该方法。
- 可以用于进行一些资源清理操作,比如关闭数据库连接、释放资源等。
- 参数
ex
代表可能发生的异常。总结起来,
preHandle
方法在请求处理方法之前被调用,可以进行一些预处理操作;postHandle
方法在请求处理方法执行后、视图渲染之前被调用,可以对请求处理结果进行后续处理;afterCompletion
方法在请求完成后被调用,可以进行一些资源清理操作。这些方法提供了拦截器在不同阶段介入请求处理流程的机会,可以用于实现一些通用的功能和逻辑。
3.创建一个springmvc配置类
继承自WebMvcConfigurationSupport表示这个类为springmvc的配置类,这样,在Spring MVC应用程序启动时,这些配置将会生效,并对应用程序的请求进行相应的处理和拦截。
重写addInterceptor()方法配置拦截器,下面是代码实现
package com.csy.config;
import com.csy.controller.interceptor.ProjectInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {
@Autowired
private ProjectInterceptor projectInterceptor;
//配置一个静态资源处理器
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
}
//配置一个拦截器
@Override
protected void addInterceptors(InterceptorRegistry registry) {
//配置拦截器
registry.addInterceptor(projectInterceptor).addPathPatterns("/books","/books/*");
}
}
具体来说,这个类继承了
WebMvcConfigurationSupport
类,并使用了@Configuration
注解,表示这是一个配置类。在这个配置类中,有两个重写的方法:
addResourceHandlers(ResourceHandlerRegistry registry)
方法用于配置静态资源处理器。通过调用registry.addResourceHandler("/pages/**").addResourceLocations("/pages/")
方法,将请求路径以"/pages/"开头的请求映射到项目中的"/pages/"目录下的静态资源文件。例如,如果有一个请求路径为"/pages/index.html",则会映射到项目中的"/pages/index.html"文件。
addInterceptors(InterceptorRegistry registry)
方法用于配置拦截器。通过调用registry.addInterceptor(projectInterceptor).addPathPatterns("/books","/books/*")
方法,将ProjectInterceptor
拦截器添加到拦截器注册表中,并指定了需要拦截的路径模式为"/books"和"/books/*"。这意味着当请求路径匹配到这两个模式时,将会触发ProjectInterceptor
的拦截逻辑。总结起来,
SpringMvcSupport
类是用来配置静态资源处理器和拦截器的