Spring Boot Component Scanning

Spring's component scanning feature automatically detects and registers beans in the application context, allowing for a clean and modular configuration. This tutorial will guide you through the process of setting up and using component scanning in a Spring Boot application.

Prerequisites

  • JDK 17 or later
  • Maven or Gradle
  • IDE (IntelliJ IDEA, Eclipse, etc.)

Step 1: Set Up a Spring Boot Project

1.1 Create a New Spring Boot Project

Use Spring Initializr to create a new project with the following dependencies:

  • Spring Web

Download and unzip the project, then open it in your IDE.

1.2 Configure application.properties

Set up the application properties for your project. This file is located in the src/main/resources directory.

# src/main/resources/application.properties

server.port=8080

Step 2: Enable Component Scanning

2.1 Create Packages for Components

Create the following package structure for your components:

com.example.demo
├── DemoApplication.java
├── controller
│   └── GreetingController.java
├── service
│   └── GreetingService.java
└── repository
    └── GreetingRepository.java

2.2 Annotate Components

Annotate your classes with the appropriate Spring annotations to make them components that can be scanned.

2.2.1 GreetingService.java

package com.example.demo.service;

import org.springframework.stereotype.Service;

@Service
public class GreetingService {

    public String getGreeting() {
        return "Hello, World!";
    }
}

Explanation:

  • @Service: Indicates that this class is a service component.

2.2.2 GreetingRepository.java

package com.example.demo.repository;

import org.springframework.stereotype.Repository;

@Repository
public class GreetingRepository {

    public String fetchGreeting() {
        return "Hello from the Repository!";
    }
}

Explanation:

  • @Repository: Indicates that this class is a repository component.

2.2.3 GreetingController.java

package com.example.demo.controller;

import com.example.demo.service.GreetingService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class GreetingController {

    @Autowired
    private GreetingService greetingService;

    @GetMapping("/greet")
    public String greet() {
        return greetingService.getGreeting();
    }
}

Explanation:

  • @RestController: Indicates that this class is a REST controller.
  • @Autowired: Injects the GreetingService bean.
  • @GetMapping("/greet"): Maps HTTP GET requests to the greet method.

Step 3: Enable Component Scanning in Spring Boot

Spring Boot automatically scans for components in the package where the main application class is located and its sub-packages. By default, it scans the package where the @SpringBootApplication annotated class resides.

3.1 Create the Main Application Class

Create the main application class in the root package.

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

Explanation:

  • @SpringBootApplication: A convenience annotation that includes @ComponentScan, which enables component scanning in the package where this class is located and its sub-packages.

3.2 Customizing Component Scan (Optional)

If your components are located outside the default package, you can customize the component scanning using the @ComponentScan annotation.

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;

@SpringBootApplication
@ComponentScan(basePackages = {"com.example.demo.service", "com.example.demo.repository", "com.example.demo.controller"})
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

Explanation:

  • @ComponentScan(basePackages = {"com.example.demo.service", "com.example.demo.repository", "com.example.demo.controller"}): Customizes the component scanning to include the specified packages.

Step 4: Running and Testing the Application

4.1 Run the Application

Run the Spring Boot application using your IDE or the command line:

./mvnw spring-boot:run

4.2 Test the Endpoint

Open your browser and navigate to http://localhost:8080/greet. You should see the following response:

Hello, World!

Step 5: Advanced Component Scanning

5.1 Using Custom Annotations for Scanning

You can create custom annotations to include components in the scanning process.

5.1.1 Create a Custom Annotation

package com.example.demo.annotation;

import org.springframework.stereotype.Service;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Service
public @interface CustomService {
}

Explanation:

  • @Target({ElementType.TYPE}): Specifies that this annotation can be applied to types (classes, interfaces, etc.).
  • @Retention(RetentionPolicy.RUNTIME): Specifies that this annotation is available at runtime.
  • @Service: Marks this annotation as a stereotype for service components.

5.1.2 Use the Custom Annotation

package com.example.demo.service;

import com.example.demo.annotation.CustomService;

@CustomService
public class CustomGreetingService {

    public String getCustomGreeting() {
        return "Hello from Custom Service!";
    }
}

5.2 Enable Custom Annotation Scanning

Enable scanning for the custom annotation using @ComponentScan.

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.FilterType;

@SpringBootApplication
@ComponentScan(basePackages = {"com.example.demo"},
               includeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = CustomService.class))
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

Explanation:

  • includeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = CustomService.class): Configures component scanning to include beans annotated with @CustomService.

Conclusion

In this tutorial, you have learned how to set up and use component scanning in a Spring Boot application. We covered:

  • Setting up a Spring Boot project.
  • Annotating classes with appropriate Spring annotations.
  • Enabling component scanning with @SpringBootApplication and @ComponentScan.
  • Customizing component scanning with custom annotations.

By leveraging component scanning, you can keep your Spring Boot application configuration clean and modular, promoting better organization and easier maintenance.


Comments