The @ServletComponentScan Annotation in Spring Boot

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:

  1. @WebServlet annotation.
  2. The @WebFilter.
  3. @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.