监听器、过滤器和拦截器

什么是拦截器与过滤器与监听器的区别是什么?

拦截器、过滤器和监听器是在Java Web开发中常用的三种组件,它们在不同层面上对请求和响应进行处理,但有一些区别:

拦截器(Interceptor):拦截器是一种在方法调用前后、异常抛出前后等关键节点进行拦截处理的组件。在Java中,拦截器通常用于AOP(面向切面编程)中,可以对方法进行增强或添加额外的逻辑。拦截器一般是针对特定的方法或类进行拦截,可以在方法执行前后做一些处理,如日志记录、权限验证等。

过滤器(Filter):过滤器是一种用于在请求到达Servlet之前或响应返回给客户端之前进行预处理或后处理的组件。过滤器可以对请求和响应进行拦截和修改,常用于实现一些通用的功能,如字符编码转换、请求参数处理、权限验证等。过滤器是基于Servlet规范的,可以对整个应用的请求进行过滤。

监听器(Listener):监听器是一种用于监听Web应用中事件发生的组件。通过监听器,可以在特定事件发生时执行相应的逻辑,如应用启动和关闭、会话创建和销毁、属性变化等。监听器可以用于在应用运行期间进行一些全局性的操作,如初始化一些资源、记录应用的状态等。

总结来说,拦截器主要用于方法调用前后的拦截处理,过滤器主要用于请求和响应的预处理和后处理,监听器主要用于监听应用中的事件发生。它们在功能上有所重叠,但在使用场景和具体实现上有一些区别。

监听器、过滤器和拦截器的执行顺序

过滤器→监听器→拦截器

监听器(Listener)的执行顺序:

应用启动时,先执行ContextListener(ServletContextListener)的contextInitialized()方法。
当会话(Session)创建时,执行HttpSessionListener的sessionCreated()方法。
当会话(Session)销毁时,执行HttpSessionListener的sessionDestroyed()方法。
当属性变化时,执行HttpSessionAttributeListener的attributeAdded()、attributeRemoved()、attributeReplaced()方法。
应用关闭时,执行ContextListener的contextDestroyed()方法。

过滤器(Filter)的执行顺序:

根据在web.xml中配置的顺序,依次执行每个过滤器的doFilter()方法。
如果有多个过滤器,按照配置的顺序依次执行,直到最后一个过滤器执行完毕后,再执行Servlet的service()方法。

拦截器(Interceptor)的执行顺序:

根据拦截器的配置顺序,依次执行每个拦截器的拦截方法(intercept())。
如果有多个拦截器,按照配置的顺序依次执行,直到最后一个拦截器执行完毕后,再执行目标方法。
需要注意的是,监听器是在应用启动和关闭、会话创建和销毁、属性变化等事件发生时触发执行;过滤器是在请求到达Servlet之前和响应返回给客户端之前进行预处理和后处理;拦截器是在方法调用前后进行拦截处理。它们之间的执行顺序是根据配置的顺序来确定的。

分页拦截器底层的执行原理

PageHelper的底层拦截器核心代码主要是通过实现MyBatis的Interceptor接口来实现的。下面是一个简化的示例代码,展示了PageHelper拦截器的核心逻辑:

public class PageInterceptor implements Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        // 获取原始的SQL语句
        MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
        BoundSql boundSql = mappedStatement.getBoundSql(invocation.getArgs()[1]);
        String originalSql = boundSql.getSql();

        // 判断原始SQL是否需要进行分页处理
        if (originalSql.contains("SELECT")) {
            // 获取分页参数
            Page<?> page = PageHelper.getLocalPage();

            if (page != null) {
                // 修改原始SQL语句,添加分页逻辑
                String pageSql = generatePageSql(originalSql, page);
                boundSql.setSql(pageSql);
            }
        }

        // 继续执行原始的查询方法
        return invocation.proceed();
    }

    // 生成分页SQL语句
    private String generatePageSql(String originalSql, Page<?> page) {
        // 根据数据库类型生成对应的分页SQL语句
        String dialect = getDatabaseDialect();
        String pageSql = dialect + " LIMIT " + page.getStartRow() + ", " + page.getPageSize();
        return pageSql;
    }

    // 获取数据库方言
    private String getDatabaseDialect() {
        // 根据配置获取数据库方言
        return "MySQL"; // 示例代码中使用MySQL作为数据库
    }

    // 其他方法省略...
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值