In Spring, you can programmatically register beans into the application context at runtime using the BeanDefinitionRegistry
or ConfigurableApplicationContext
. Below are different approaches depending on your use case:
1. Using BeanDefinitionRegistry
The BeanDefinitionRegistry
interface can be used to dynamically register bean definitions in the Spring context. ApplicationContext
implementations like AnnotationConfigApplicationContext
or GenericApplicationContext
expose a BeanDefinitionRegistry
.
Here’s an example:
package org.kodejava.spring;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class DynamicBeanRegistrationExample {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
// Get the BeanDefinitionRegistry
DefaultListableBeanFactory beanFactory = context.getDefaultListableBeanFactory();
// Create a bean definition
RootBeanDefinition beanDefinition = new RootBeanDefinition(MyBean.class);
// Register the bean definition with a specific name
beanFactory.registerBeanDefinition("myBean", beanDefinition);
// Refresh the context to reflect changes
context.refresh();
// Access the dynamically added bean
MyBean myBean = context.getBean(MyBean.class);
myBean.sayHello();
context.close();
}
static class MyBean {
public void sayHello() {
System.out.println("Hello from MyBean!");
}
}
}
Explanation:
- The
DefaultListableBeanFactory
is used to register a bean definition. - The
RootBeanDefinition
object allows you to define the settings for the bean. - The
refresh()
method lets the application context pick up the newly added bean definitions.
2. Using ConfigurableApplicationContext
The ConfigurableApplicationContext
provides methods like register
to directly add a class to the Spring context.
Here’s an example:
package org.kodejava.spring;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class DynamicBeanRegistrationExample2 {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
// Register a configuration class or bean type directly
context.register(MyBean.class);
// Refresh the context to reflect the bean
context.refresh();
// Access the dynamically added bean
MyBean myBean = context.getBean(MyBean.class);
myBean.sayHello();
context.close();
}
static class MyBean {
public void sayHello() {
System.out.println("Hello from MyBean!");
}
}
}
Explanation:
- The
register
method dynamically registers a@Component
,@Bean
, or class definition into the Spring context.
3. Using GenericApplicationContext
A GenericApplicationContext
allows for dynamic bean registrations through registerBean()
.
Here’s an example:
package org.kodejava.spring;
import org.springframework.context.support.GenericApplicationContext;
public class DynamicBeanRegistrationExample3 {
public static void main(String[] args) {
GenericApplicationContext context = new GenericApplicationContext();
// Programmatically register a bean with a name and configuration
context.registerBean(MyBean.class, () -> new MyBean());
// Refresh the context to apply changes
context.refresh();
// Access the dynamically added bean
MyBean myBean = context.getBean(MyBean.class);
myBean.sayHello();
context.close();
}
static class MyBean {
public void sayHello() {
System.out.println("Hello from MyBean!");
}
}
}
Explanation:
- The
registerBean
method registers a bean class along with aSupplier
object that provides the bean instance.
4. Using an ApplicationContextInitializer
If you want to register beans at the application startup phase, you can use an ApplicationContextInitializer
.
Example:
package org.kodejava.spring;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.GenericApplicationContext;
public class MyInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
if (applicationContext instanceof GenericApplicationContext) {
GenericApplicationContext genericContext = (GenericApplicationContext) applicationContext;
// Register a bean dynamically
genericContext.registerBean(MyBean.class, MyBean::new);
}
}
static class MyBean {
public void sayHello() {
System.out.println("Hello from MyBean!");
}
}
}
To use this initializer, you would pass it when initializing your Spring application, for example:
new SpringApplicationBuilder(MyApplication.class)
.initializers(new MyInitializer())
.run(args);
Things to Keep in Mind
- Bean Scope: You can set the scope (
singleton
,prototype
, etc.) of a bean when registering it dynamically. - Dependencies: Ensure that you properly handle dependencies for dynamically registered beans.
- Refresh Lifecycle: In most cases, you will need to call
refresh()
on theApplicationContext
after registering a new bean to allow Spring to process it.
By using these approaches, you can register beans into the Spring context programmatically at runtime.
Maven Dependencies
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>6.2.6</version>
</dependency>