Finding All Beans with a Custom Annotation in Spring boot
Last Updated :
23 Jul, 2025
In Spring Boot, developers often define beans (components, services, etc.) to be managed automatically by the Spring IoC (Inversion of Control) container. Sometimes, it's helpful to identify beans marked with a specific custom annotation for special handling—whether for applying certain behavior or managing the execution flow.
In this article, we will explore how to create a Spring Boot application that scans and retrieves all beans annotated with a custom annotation. We will cover:
- Creating a custom annotation.
- Annotating beans (e.g., services) with the custom annotation.
- Scanning the application context to find the beans with that custom annotation.
Custom Annotations in Spring
Annotations in Spring are powerful tools for marking classes or methods with metadata. While Spring provides many built-in annotations like @Service or @Component, you can also define custom annotations. These annotations can be applied to specific beans, which can then be identified at runtime for special processing.
To achieve this, the steps are:
- Define the custom annotation.
- Annotate beans with this custom annotation.
- Implement a utility to scan the Spring application context and find beans annotated with the custom annotation.
Implementation to find all beans with a Custom Annotation
Let’s walk through the steps to find all beans annotated with a custom annotation in a Spring Boot application.
Step 1: Create a New Spring Boot Project
Create a new Spring Boot project using IntelliJ IDEA or your preferred IDE. Choose the following options:
- Name:
find-annotated-beans - Language: Java
- Type: Maven
- Packaging: Jar
Click on the Next button.
Project MetadataStep 2: Add the Dependencies
Add the following dependencies into the Spring Boot Project.
- Spring Web
- Lombok
- Spring Boot DevTools
Click on the Create button.
Add DependenciesProject Structure
After the project creation done successfully, the folder structure will look like the below image:P
Project Folder StructureStep 3: Configure Application Properties
In the application.properties file, set up the project name and port.
spring.application.name=find-annotated-beans
server.port=8080
Step 4: Create the CustomAnnotation Interface
This is our custom annotation, which will be used to mark certain beans.
CustomAnnotation.java
Java
package com.gfg.findannotatedbeans.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE) // Can be used on classes or interfaces
@Retention(RetentionPolicy.RUNTIME) // Retain annotation at runtime
public @interface CustomAnnotation {
}
Step 5: Create the Annotated Beans
Now, let’s create two service classes that will be annotated with @CustomAnnotation.
AnnotatedService1.java:
Java
package com.gfg.findannotatedbeans.services;
import com.gfg.findannotatedbeans.annotations.CustomAnnotation;
import org.springframework.stereotype.Service;
@Service
@CustomAnnotation
public class AnnotatedService1 {
public void doSomething() {
System.out.println("AnnotatedService1 is doing something...");
}
}
AnnotatedService2.java:
Java
package com.gfg.findannotatedbeans.services;
import com.gfg.findannotatedbeans.annotations.CustomAnnotation;
import org.springframework.stereotype.Service;
@Service
@CustomAnnotation
public class AnnotatedService2 {
public void doSomething() {
System.out.println("AnnotatedService2 is doing something...");
}
}
These beans are annotated with @CustomAnnotation. They represent services that will be discovered by our scanner.
Step 6: Configure the Scanner to Run the Startup
We will configure the Spring Boot application to scan for the beans annotated with @CustomAnnotation during the startup.
BeanScannerConfig.java
Java
package com.gfg.findannotatedbeans.config;
import com.gfg.findannotatedbeans.annotations.CustomAnnotation;
import com.gfg.findannotatedbeans.util.CustomAnnotationBeanScanner;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class BeanScannerConfig {
private final CustomAnnotationBeanScanner customAnnotationBeanScanner;
public BeanScannerConfig(CustomAnnotationBeanScanner customAnnotationBeanScanner) {
this.customAnnotationBeanScanner = customAnnotationBeanScanner;
}
@Bean
public CommandLineRunner commandLineRunner() {
return args -> {
customAnnotationBeanScanner.findBeansWithCustomAnnotation(CustomAnnotation.class);
};
}
}
By using CommandLineRunner, this configuration ensures that the bean scanner runs when the application starts up, searching for beans annotated with @CustomAnnotation.
Step 7: Create the CustomAnnotationBeanScanner Utility
We need a utility class to scan the application context for beans annotated with @CustomAnnotation.
CustomAnnotationBeanScanner.java
Java
package com.gfg.findannotatedbeans.util;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.stereotype.Component;
import java.util.Map;
@Component
public class CustomAnnotationBeanScanner {
private final ListableBeanFactory beanFactory;
public CustomAnnotationBeanScanner(ListableBeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
public void findBeansWithCustomAnnotation(Class annotationType) {
Map<String, Object> beans = beanFactory.getBeansWithAnnotation(annotationType);
beans.forEach((beanName, beanInstance) -> {
System.out.println("Bean found: " + beanName + " of type " + beanInstance.getClass().getSimpleName());
});
}
}
- BeanScannerConfig: This configuration ensures that the scanner is triggered at the application startup using the CommandLineRunner.
- The findBeansWithCustomAnnotation method scans the Spring context for the beans annotated with @CustomAnnotation and prints them to the console.
Step 8: Main class
No changes are required in the main class.
Java
package com.gfg.findannotatedbeans;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class FindAnnotatedBeansApplication {
public static void main(String[] args) {
SpringApplication.run(FindAnnotatedBeansApplication.class, args);
}
}
pom.xml
XML
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://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>3.3.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.gfg</groupId>
<artifactId>find-annotated-beans</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>find-annotated-beans</name>
<description>find-annotated-beans</description>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<java.version>17</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-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</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>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
Step 9: Run the Application
Once you've set everything up, run the application. It will scan the application context and print out all the beans annotated with @CustomAnnotation to the console:
OutputThis example project demonstrates how to create the Spring Boot application that scans for the beans with the custom annotation. It can be extended to support the more complex scenarios by modifying the annotation scanner or adding the more annotated beans.
Conclusion
In this article, we explored how to create a custom annotation and use it to mark beans in a Spring Boot application. We then implemented a scanner utility that searches the application context for beans annotated with the custom annotation. This method provides flexibility for applying special behavior to specific beans at runtime.
Explore
Java Enterprise Edition
Multithreading
Concurrency
JDBC (Java Database Connectivity)
Java Frameworks
JUnit