In this post, we will explore the @ServletComponentScan annotation in Spring Boot. Spring Boot provides several annotations for easy use and the @ServletComponentScan is one of those annotations.
Introduction
the @ServletComponentScan annotation automatically register the following Servlet components for embedded web servers. This annotation supports the following Servlet 3.0 annotations:
@WebServlet
annotation.- The
@WebFilter
. @WebListener
annotation
To register these classes automatically, we need to annotate our main class with the @ServletComponentScan annotation. Before we get in to the example, lets quickly take a brief look at these three annotation and their use cases.
[pullquote align=”normal”]We will only use @ServletComponentScan
when the application needs to run in embedded container. [/pullquote]
1. @WebServlet Annotation
The @WebServlet
annotation introduced in the Servlet 3.0 specification allows us to define a servlet classes.
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet("/greeting")
public class GreetingServlet extends HttpServlet {
@Override
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().write("Greeting from the Servlet");
resp.flushBuffer();
}
}
2. @WebFilter
This is how our filter component looks like:
package com.javadevjournal.filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@WebFilter("/greeting")
public class GreetingFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("filter for greeting project");
filterChain.doFilter(servletRequest,servletResponse);
}
}
3. @WebListner Annotation
package com.javadevjournal.listner;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
@WebListener
public class CustomListner implements ServletContextListener {
@Override
public void contextInitialized (ServletContextEvent servletContextEvent) {
System.out.println("from ServletContextListener: " +
" context initialized");
servletContextEvent.getServletContext().setAttribute("greeting", "Hello from project Greetings!!!");
}
@Override
public void contextDestroyed (ServletContextEvent servletContextEvent) {
}
}
4. Why @ServletComponentScan annotation
You might ask why do we need the @ServletComponentScan annotation in Spring Boot? If you are working on the Spring Boot, you might already know the fact that Spring Boot use embedded container for the deployment (until we deploy it on external container). The embedded container does not support the @WebServlet
, @WebFilter
and @WebListener
annotations. To handle it and support these annotations. Spring Boot introduced the new @ServletComponentScan
annotation.
4.1 Maven Setup
To use these Servlet 3.0 annotations in the Spring Boot application, we only need to add the web starter in the pom.xml
file. This is how our pom.xml
file looks like:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
<relativePath/>
<!-- lookup parent from repository -->
</parent>
<groupId>com.javadevjournal</groupId>
<artifactId>servlet-component-scan-annotation</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>com.javadevjournal.servlet-component-scan-annotation</name>
<description>Project for ServletComponentScan</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
5. Using @ServletComponentScan
To enable scanning for the @WebServlet
, @WebFilter
and @WebListener
annotations, add the @ServletComponentScan
annotation to the main class. This is how it looks like:
@SpringBootApplication
@ServletComponentScan
public class ServletComponentScanAnnotationApplication {
public static void main(String[] args) {
SpringApplication.run(ServletComponentScanAnnotationApplication.class, args);
}
}
5.1. Package Scanning
By default the @ServletComponentScan annotation scanning work similar to the @SpringBootApplication annotation and it scan from the package of the annotated class. If you want to customize, we can do that by using
- value
- basePackages
- basePackageClasses
parameters available in the annotation.Here are some ways to do this:
@ServletComponentScan("com.javadevjournal.components")
public class ServletComponentScanAnnotationApplication {}
// other option
@ServletComponentScan(basePackages = "com.javadevjournal.components")
public class ServletComponentScanAnnotationApplication {}
Summary
In this post, we explored the @ServletComponentScan annotation in Spring Boot. We saw why spring boot introduced this annotation and how can we use this annotation in the embedded container to use Servlet 3.0 annotations. As always, the source code for this article is available on the GitHub.