Mastering Spring BeanRegistrar: Fine-Grained Programmatic Bean Registration
This article explains how to use Spring's BeanRegistrar interface to programmatically register beans with precise scope, lazy initialization, and custom providers, providing code examples that demonstrate registering default and prototype beans and accessing them via a CommandLineRunner.
BeanRegistraris an interface for scenarios where you want to register beans programmatically into the application context, without relying on @Bean, @Configuration or @Component, by using the abstract BeanRegistry to register beans dynamically.
https://docs.spring.io/spring-framework/docs/7.0.0-M3/javadoc-api/org/springframework/beans/factory/BeanRegistrar.html
1. Advantages of BeanRegistrar
Using BeanRegistrar compared with traditional annotation‑based bean configuration offers the following benefits:
Fine‑grained control : you can precisely define a bean’s scope, initialization strategy and provider instead of relying solely on annotations.
Configuration‑file‑specific setup : beans can be conditionally registered based on the active profile, enabling flexible runtime customization.
Lazy initialization and prototype scope : supports advanced lifecycle management to optimise resource usage.
Support for advanced runtime scenarios : applications using BeanRegistrar can achieve better performance and compatibility in ahead‑of‑time compiled environments.
2. Example: Using BeanRegistrar for Simple Bean Registration
We demonstrate with a simple GreetingService example. Instead of annotating the class with @Service or @Bean, we register it dynamically via BeanRegistrar.
public class GreetingService {
private final String greeting;
public GreetingService() {
this("Hello");
}
public GreetingService(String greeting) {
this.greeting = greeting;
}
public String greet(String name) {
return greeting + ", " + name + "!";
}
}Here, GreetingService provides a customizable greeting message.
Using BeanRegistrar to Register Bean
We create a configuration class that imports a custom registrar.
@Configuration
@Import(GreetingServiceRegistrar.class)
public class AppConfig {
}
class GreetingServiceRegistrar implements BeanRegistrar {
@Override
public void register(BeanRegistry registry, Environment env) {
// Register the default GreetingService
registry.registerBean("greetingService", GreetingService.class);
// Register a prototype, lazy‑init bean with a custom provider
registry.registerBean("customGreetingService", GreetingService.class, spec ->
spec.prototype()
.lazyInit()
.description("Custom GreetingService bean")
.supplier(context -> new GreetingService("Hi there")));
}
}In this configuration we first register a default bean named greetingService. Then we add a second bean customGreetingService defined as prototype scope, lazy‑initialized, with a custom factory that supplies a different greeting.
Using the Registered Bean
Once beans are registered programmatically, they can be retrieved and used like any other Spring‑managed bean. A simple way to demonstrate this is to create a CommandLineRunner that obtains the beans from the application context and invokes them.
@Component
public class GreetingRunner implements CommandLineRunner {
private final ApplicationContext context;
public GreetingRunner(ApplicationContext context) {
this.context = context;
}
@Override
public void run(String... args) {
GreetingService defaultService = context.getBean("greetingService", GreetingService.class);
GreetingService customService = context.getBean("customGreetingService", GreetingService.class);
System.out.println(defaultService.greet("Spring Developer"));
System.out.println(customService.greet("Spring Boot User"));
}
}This runner fetches the default and custom GreetingService beans and calls their greet() methods. The default bean uses the standard constructor message, while the custom bean uses the message supplied by its custom provider.
Console Output
Hello, Spring Developer!
Hi there, Spring Boot User!3. Conclusion
In this article we explored how to use Spring's BeanRegistrar to programmatically register beans with different scopes, lazy initialization, and custom providers. This approach gives developers fine‑grained control over bean registration, especially for advanced use cases where annotations alone are insufficient.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Cognitive Technology Team
Cognitive Technology Team regularly delivers the latest IT news, original content, programming tutorials and experience sharing, with daily perks awaiting you.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
