news 2026/4/15 16:16:14

Java过滤器-拦截器-AOP-Controller

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Java过滤器-拦截器-AOP-Controller

1 对比

组件核心用途主要应用场景
过滤器 (Filter)在请求到达Servlet之前或响应返回客户端之前,对原始的ServletRequestServletResponse进行预处理或后处理。字符编码设置、敏感词过滤、URL级别的权限认证、请求日志记录。‌12
拦截器 (Interceptor)在请求进入Controller方法前后,以及视图渲染前后,对请求进行拦截和处理。它基于Spring的反射机制。权限认证、审计日志、请求参数预处理、响应数据包装。‌12
切面 (AOP)通过“切面”技术,在不修改目标方法代码的情况下,横向切入业务逻辑,实现功能的扩展和解耦。它基于动态代理(如JDK Proxy或CGLIB)。方法级别的权限控制、日志记录、事务管理、缓存操作、方法执行时间监控。‌13
ControllerAdvice全局异常处理和数据绑定/预处理,专门用于增强Controller层。(也是基于AOP)统一的全局异常处理、统一的数据格式化、统一的请求参数预处理。‌13

使用过程中需要注意执行顺序和和优先级。

2 Servlet

在Java Web应用程序中,Servlet是处理HTTP请求和响应的核心组件,Servlet的生命周期:

1 加载和实例化
当服务器启动时,会加载web.xml中配置的Servlet或者在注解为@WebServlet的类。
服务器将为每个Servlet创建一个实例。

2. 初始化
在Servlet实例创建后,会调用init(ServletConfig config)方法进行初始化。
这个方法通常用于执行仅需执行一次的初始化操作,比如加载资源文件、打开数据库连接等。

3. 请求处理
当客户端发送请求到服务器时,服务器会调用Servlet的service(ServletRequest req, ServletResponse res)方法。
在Servlet 3.0及更高版本中,推荐使用doGet(HttpServletRequest request, HttpServletResponse response)
和doPost(HttpServletRequest request, HttpServletResponse response)等方法来分别处理GET和POST请求。

4. 服务
在每次接收到新的请求时,service方法或相应的doXxx方法会被调用,用于处理请求并生成响应。

5. 销毁
当Web应用被卸载或服务器关闭时,会调用Servlet的destroy()方法。这个方法用于释放资源,比如关闭数据库连接、停止线程等。

注意事项:
‌单例性‌:默认情况下,Servlet是单例的,即整个Web应用生命周期内只会有一个Servlet实例。这意味着所有的客户端请求将共享同一个Servlet实例。如果Servlet需要处理大量并发请求,应确保其线程安全。
‌多线程‌:由于Servlet是单例的,多个请求可能会并发地执行service方法或其子方法(如doGet, doPost)。因此,编写Servlet时需要考虑线程安全。可以使用同步块或并发工具类来管理共享资源的访问。
‌生命周期管理‌:可以通过覆盖init和destroy方法来管理资源的初始化和清理工作。对于非单例的Servlet,可以使用@WebServlet(value="/path", loadOnStartup=1)注解来控制加载顺序和时机

3 动态代理

维度Java动态代理‌(基于JDK)CGLIB代理‌(基于ASM)
实现原理通过反射机制生成实现目标接口的代理类通过ASM字节码操作生成目标类的子类
适用场景目标类必须实现接口目标类无需实现接口,支持类级别的代理
性能通常稍逊于CGLIB,但差异可忽略性能更优,尤其在无接口场景下
限制无法代理final类或方法无法代理final类
实现方式java.lang.reflect.Proxy+InvocationHandlernet.sf.cglib.proxy.Enhancer
使用场景接口多、结构清晰的项目无接口类、老项目或性能敏感场景

JDK Proxy

反射和接口

import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; // 定义目标接口 interface TargetInterface { void doSomething(); } // 实现目标接口 class TargetImpl implements TargetInterface { @Override public void doSomething() { System.out.println("TargetImpl method"); } } // 代理处理器 class TargetProxy implements InvocationHandler { private TargetInterface targetInterface; public TargetProxy(TargetInterface targetInterface) { this.targetInterface = targetInterface; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println(method.getName() + "前置处理"); Object result = method.invoke(targetInterface, args); System.out.println(method.getName() + "后置处理"); return result; } public TargetInterface getProxyInstance() { return (TargetInterface) Proxy.newProxyInstance( TargetProxy.class.getClassLoader(), targetInterface.getClass().getInterfaces(), this ); } } // 测试类 public class JDKDynamicProxyExample { public static void main(String[] args) { TargetInterface target = new TargetImpl(); TargetProxy proxyHandler = new TargetProxy(target); TargetInterface proxy = proxyHandler.getProxyInstance(); proxy.doSomething(); } }

CGLIb

SM字节码操作生成目标类的子类

public class TargetClass { public void doSomething() { System.out.println("TargetClass.doSomething()执行"); } public String getValue(String input) { return "处理结果: " + input; } } import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; import java.lang.reflect.Method; public class MyMethodInterceptor implements MethodInterceptor { @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("前置增强: " + method.getName()); Object result = proxy.invokeSuper(obj, args); // 调用父类方法 System.out.println("后置增强: " + method.getName()); return result; } } import net.sf.cglib.proxy.Enhancer; public class CglibProxyDemo { public static void main(String[] args) { // 创建Enhancer对象 Enhancer enhancer = new Enhancer(); // 设置父类 enhancer.setSuperclass(TargetClass.class); // 设置回调 enhancer.setCallback(new MyMethodInterceptor()); // 创建代理对象 TargetClass proxy = (TargetClass) enhancer.create(); // 调用方法 proxy.doSomething(); String result = proxy.getValue("CGLIB测试"); System.out.println(result); } }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/15 16:15:00

jQuery圆形进度条插件:创建动态环形进度指示器的完整指南

jQuery圆形进度条插件:创建动态环形进度指示器的完整指南 【免费下载链接】jquery-circle-progress jQuery Plugin to draw animated circular progress bars 项目地址: https://gitcode.com/gh_mirrors/jq/jquery-circle-progress 在现代网页开发中&#xf…

作者头像 李华
网站建设 2026/4/11 8:47:27

Wan2.2-T2V-5B本地化部署方案:保护数据隐私的最佳实践

Wan2.2-T2V-5B本地化部署方案:保护数据隐私的最佳实践你有没有想过,一个能“看懂文字就生成视频”的AI模型,居然能在你的办公室服务器上安静运行,连一比特数据都不用上传到云端?🤯 这听起来像科幻片的桥段&…

作者头像 李华
网站建设 2026/4/13 1:52:10

Wan2.2-T2V-A14B助力地方文旅局打造城市IP形象视频

Wan2.2-T2V-A14B助力地方文旅局打造城市IP形象视频 你有没有刷到过那种让人眼前一亮的城市宣传片?夜幕下的西湖泛着微光,汉服少女提灯走过石桥,远处雷峰塔灯火通明,突然一条金龙从湖面腾起——画面电影感拉满,情绪瞬间…

作者头像 李华
网站建设 2026/4/5 8:34:50

Wan2.2-T2V-A14B模型轻量化改造方案探索

Wan2.2-T2V-A14B模型轻量化改造方案探索 在短视频井喷、内容创作门槛不断降低的今天,AI生成技术正从“炫技”走向“实干”。尤其是文本到视频(Text-to-Video, T2V)这类高复杂度多模态任务,已经不再是实验室里的玩具——它正在影视…

作者头像 李华
网站建设 2026/4/8 22:46:55

图书管理|基于springboot + vue图书管理系统(源码+数据库+文档)

图书管理 目录 基于springboot vue图书管理系统 一、前言 二、系统功能演示 三、技术选型 四、其他项目参考 五、代码参考 六、测试参考 七、最新计算机毕设选题推荐 八、源码获取: 基于springboot vue图书管理系统 一、前言 博主介绍:✌️大…

作者头像 李华
网站建设 2026/4/14 22:07:57

出行旅游安排|基于springboot + vue出行旅游安排系统(源码+数据库+文档)

出行旅游安排 目录 基于springboot vue出行旅游安排系统 一、前言 二、系统功能演示 三、技术选型 四、其他项目参考 五、代码参考 六、测试参考 七、最新计算机毕设选题推荐 八、源码获取: 基于springboot vue出行旅游安排系统 一、前言 博主介绍&…

作者头像 李华