From web.xml to Spring Boot: How Java Servlets and Filters Evolved

This article walks through the evolution of Java web development, comparing the classic web.xml configuration with Servlet 3.0 annotations, Spring’s ServletContainerInitializer, and Spring Boot’s embedded‑container registration mechanisms, while exposing the underlying source code and initialization flow.

Programmer DD
Programmer DD
Programmer DD
From web.xml to Spring Boot: How Java Servlets and Filters Evolved

Java web applications traditionally started with web.xml to declare servlet and filter mappings, a process that was later simplified by Servlet 3.0’s annotations ( @WebServlet, @WebFilter) and dynamic registration via ServletContext. Spring adopted this approach through SpringServletContainerInitializer, which discovers WebApplicationInitializer implementations and registers the DispatcherServlet and other components.

Servlet 3.0 Features

Servlet 3.0 introduces annotation‑based configuration and runtime registration methods such as ServletContext.addServlet and addFilter. The article shows a minimal example of a HelloWorldServlet and HelloWorldFilter using these APIs, and explains the required web.xml entries for legacy setups.

Spring’s Integration

Spring’s SpringServletContainerInitializer is marked with @HandlesTypes(WebApplicationInitializer.class). During container startup it loads all WebApplicationInitializer beans, sorts them, and invokes their onStartup(ServletContext) methods. The core implementation resides in AbstractDispatcherServletInitializer, which registers the DispatcherServlet without any web.xml.

Spring Boot Loading Process

Spring Boot does not rely on the standard ServletContainerInitializer SPI when running with an embedded container. Instead it uses its own ServletContextInitializer interface (in org.springframework.boot.web.servlet) and the EmbeddedWebApplicationContext lifecycle:

onRefresh() creates an anonymous ServletContextInitializer that calls selfInitialize.

createEmbeddedServletContainer() obtains an EmbeddedServletContainerFactory (e.g., TomcatEmbeddedServletContainerFactory) and calls getSelfInitializer() to obtain the initializer.

getSelfInitializer() returns the anonymous initializer which invokes selfInitialize(ServletContext).

selfInitialize() registers web‑application scopes, then calls getServletContextInitializerBeans().

getServletContextInitializerBeans() builds a ServletContextInitializerBeans collection that gathers all ServletContextInitializer, Servlet, Filter, and EventListener beans from the Spring context.

ServletContextInitializerBeans sorts the beans (using Ordered) and stores them for later execution.

During Tomcat startup, TomcatStarter (which implements ServletContainerInitializer) receives the array of ServletContextInitializer instances and invokes each onStartup(ServletContext), effectively registering all servlets, filters, and listeners discovered by Spring Boot.

Registration Options in Spring Boot

Annotation + @ServletComponentScan : Directly use @WebServlet and @WebFilter on classes and enable scanning.

RegistrationBean : Declare ServletRegistrationBean and FilterRegistrationBean as @Bean methods for programmatic registration.

Custom ServletContextInitializer : Implement ServletContextInitializer to call ServletContext.addServlet and addFilter manually.

The article also explains how TomcatStarter is wired into the embedded Tomcat via TomcatEmbeddedServletContainerFactory, and why Spring Boot deliberately bypasses the standard SPI to support both executable JARs and traditional WAR deployments.

Conclusion

While legacy Java web projects rely on web.xml, modern applications can use Servlet 3.0 annotations, Spring’s initializer chain, or Spring Boot’s ServletContextInitializer to register servlets, filters, and listeners. Understanding each layer—from the original XML configuration to the six‑step initialization flow in Spring Boot—helps developers choose the most appropriate registration strategy for their projects.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaSpring BootWeb DevelopmentServletInitializationServlet 3.0Embedded Tomcat
Programmer DD
Written by

Programmer DD

A tinkering programmer and author of "Spring Cloud Microservices in Action"

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.