web.xml中的和加载顺序是什么

容器先初始化所有再初始化所有,且均按web.xml中声明顺序执行init;请求处理时按顺序执行filter,再调用匹配的servlet。

加载顺序是什么">

web.xml 中的 本身没有直接的“加载顺序”依赖,但它们的 初始化顺序 是有明确规则的:容器先初始化所有 ,再初始化所有

filter 初始化早于 servlet

据 Servlet 规范,Web 容器(如 Tomcat)在应用启动时按以下顺序处理:

  • 解析 web.xml,收集所有 声明
  • 按 web.xml 中声明的**先后顺序**,依次调用每个 Filter.init()
  • 再按 web.xml 中声明的**先后顺序**,依次调用每个 Servlet.init()

也就是说,哪怕某个 servlet 在 web.xml 中写在 filter 前面,只要它被声明为 ,就不会比任何 先 init —— 规范强制要求 filter 优先就绪。

filter-mapping 和 servlet-mapping 决定执行顺序

真正影响请求处理流程的是映射(mapping)配置,而非声明顺序:

  • 中的 决定了哪些请求会经过该 filter
  • 决定了哪个 servlet 负责处理匹配的请求
  • 当一个请求同时匹配多个 filter 和一个 servlet 时,执行顺序是:
    → 所有匹配的 filter(按 在 web.xml 中的顺序)→ 目标 servlet → filter 链逆序执行 doFilter 后续逻辑(即“出栈”)

可通过 load-on-startup 控制 servlet 初始化时机

虽然 servlet 总是在 filter 之后初始化,但你可以用 指定 servlet 的相对优先级(仅限 servlet 之间):

  • 值越小越早 init(如 0 比 1 早)
  • 未设置或负数,则在首次请求时才初始化
  • 这个值对 filter 无效 —— filter 默认都是启动时加载,且不支持 load-on-startup

实际开发建议

不必纠结“谁先加载”,重点应放在:

  • 确保 filter 不依赖尚未 init 的 servlet(因为 servlet 此时确实还没 ready)
  • 把公共逻辑(如编码、登录检查、日志)放在 filter,业务逻辑放 servlet
  • 多个 filter 之间注意顺序:比如 CharacterEncodingFilter 应放在其他 filter 前面,才能保证后续 filter 读取参数时编码正确

基本上就这些。规范很明确,行为可预期,关键还是 mapping 配得对不对。