How to Register Spring Beans at Runtime: A Step‑by‑Step Guide
This tutorial explains multiple ways to register Spring beans dynamically at runtime, covering BeanDefinitionRegistryPostProcessor implementation, programmatic bean creation with BeanDefinitionBuilder, ApplicationContextInitializer usage, BeanFactory registration, and direct BeanDefinitionRegistry manipulation, complete with code examples and configuration details.
1. Overview
In this article we learn how to register a Spring Bean at runtime . Sometimes you need to add beans conditionally or programmatically.
2. Spring Bean Registration – BeanDefinitionRegistryPostProcessor
One approach is to use BeanDefinitionRegistryPostProcessor. The ApplicationContext automatically detects BeanFactoryPostProcessor beans and applies them before other beans are created. BeanFactoryPostProcessor is an extension point for customizing bean definitions before instantiation. BeanDefinitionRegistryPostProcessor allows registering additional bean definitions before the regular BeanFactoryPostProcessor detection starts.
2.1 Implement BeanDefinitionRegistryPostProcessor
Create an implementation of BeanDefinitionRegistryPostProcessor and override the postProcessBeanDefinitionRegistry method. The class is annotated with @Component so Spring can scan it.
@Component
public static class BeanRegistration implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry bdr) throws BeansException {
// custom registration logic
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory clbf) throws BeansException {
// optional bean factory processing
}
}2.2 Programmatic Bean Registration
The postProcessBeanDefinitionRegistry method receives the bean definition registry, where you can call registerBeanDefinition with a bean name and a BeanDefinition. Use BeanDefinitionBuilder (available since Spring 2.0) to create a bean definition programmatically.
bdr.registerBeanDefinition(
"customBean",
BeanDefinitionBuilder.genericBeanDefinition(CustomBean.class,
() -> new CustomBean("CustomBeanConstructorArgument"))
.getBeanDefinition()
);Another example using the generic builder method:
public static <T> BeanDefinitionBuilder genericBeanDefinition(Class<T> beanClass, Supplier<T> instanceSupplier) {
// builder implementation
}
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry bdr) throws BeansException {
bdr.registerBeanDefinition(
"customBean",
BeanDefinitionBuilder.genericBeanDefinition(CustomBean.class,
() -> new CustomBean("CustomBeanConstructorArgument"))
.getBeanDefinition()
);
}3. Register Bean with ApplicationContextInitializer
Implement ApplicationContextInitializer to run code before the Spring application context is fully created.
public class ProgrammaticApplicationContextInitializer implements ApplicationContextInitializer<GenericApplicationContext> {
@Override
public void initialize(GenericApplicationContext applicationContext) {
applicationContext.registerBean(CustomBean.class, "CustomBean initialization");
}
}If you are not using Spring Boot, you can register the initializer manually:
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext =
new AnnotationConfigApplicationContext(BeanfactoryApplication.class);
ProgrammaticApplicationContextInitializer initializer = new ProgrammaticApplicationContextInitializer();
initializer.initialize(applicationContext);
}With Spring Boot you can add the initializer via the builder:
@Configuration
@EnableAutoConfiguration
@ComponentScan
public class BeanfactoryApplication {
public static void main(String[] args) {
new SpringApplicationBuilder(BeanfactoryApplication.class)
.initializers(new ProgrammaticApplicationContextInitializer())
.run(args);
}
}You can also register the initializer in META-INF/spring.factories:
org.springframework.context.ApplicationContextInitializer=\
com.tedblob.ProgrammaticApplicationContextInitializerOr add it to web.xml for a Spring Web application:
<context-param>
<param-name>contextInitializerClasses</param-name>
<param-value>com.tedblob.ProgrammaticApplicationContextInitializer</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>It can also be set via application properties:
context.initializer.classes=com.tedblob.ProgrammaticApplicationContextInitializer4. Register Runtime Bean with BeanFactory
You can call registerBean on a BeanFactory or ApplicationContext, but this does not create a bean definition.
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanfactoryApplication.class);
applicationContext.registerBean(CustomBean.class, "custom");
CustomBean customBean = applicationContext.getBean(CustomBean.class);
System.out.println(customBean.getValue() + "");5. Register Runtime Bean with BeanDefinitionRegistry
BeanDefinitionRegistryis the sole interface in Spring’s bean factory package that encapsulates bean definition registration. You can dynamically add or remove bean definitions.
To register a new bean definition:
registry.registerBeanDefinition(beanId, newBeanObj);To remove an existing bean definition:
registry.removeBeanDefinition(beanId);Example of removing and then adding a bean at runtime:
AutowireCapableBeanFactory factory = applicationContext.getAutowireCapableBeanFactory();
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) factory;
registry.removeBeanDefinition(beanId);
registry.registerBeanDefinition(beanId, newBeanObj);6. Summary
We have covered how to register a Spring bean at runtime using several techniques, including BeanDefinitionRegistryPostProcessor, programmatic bean creation with BeanDefinitionBuilder, ApplicationContextInitializer, direct BeanFactory registration, and direct manipulation of BeanDefinitionRegistry. The full source code is available in the GitHub repository linked in the article.
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.
