How do I programmatically register beans into the Spring context at runtime?

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 a Supplier 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 the ApplicationContext 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>

Maven Central

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.