How to Dynamically Register Beans in Spring Boot 3 Using BeanDefinitionRegistryPostProcessor

This article demonstrates how to dynamically register Spring Boot 3 beans using BeanDefinitionRegistryPostProcessor and configuration properties, covering property setup, bean class definition, post‑processor implementation, registration in a configuration class, and a CommandLineRunner test that prints the created beans.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
How to Dynamically Register Beans in Spring Boot 3 Using BeanDefinitionRegistryPostProcessor

1. Introduction

Spring Boot supports dynamic bean registration via several mechanisms; @Profile is a basic way, but more flexible approaches combine programmatic bean registration or conditional bean loading.

@Profile dynamic switching – activate different beans based on environment variables such as spring.profiles.active.

Programmatic bean registration – use BeanDefinitionRegistryPostProcessor or ImportBeanDefinitionRegistrar to register beans at runtime.

Conditional bean loading – use @Conditional with custom conditions to control bean creation.

For this article we focus on using BeanDefinitionRegistryPostProcessor together with configuration properties to register beans dynamically.

2. Practical Example

2.1 Property configuration

pack:
  app:
    client:
    - name: xxx
      url: http://localhost:8081/sse
      appId: s-0001
      appKey: 111111
    - name: ooo
      url: http://localhost:8082/sse
      appId: s-0002
      appKey: 222222

The property pack.app.clients is a List; we want each element to become a bean whose name is the name attribute.

2.2 Bean definition

public class AppClient {
  private String name;
  private String url;
  private String appId;
  private String appKey;
  // getters, setters
}

We map each configuration item to an AppClient instance and register it as a bean.

2.3 PostProcessor for dynamic registration

Implement BeanDefinitionRegistryPostProcessor to read the list from the environment, create AppClient objects, and register them.

public class AppClientPostProcessor implements BeanDefinitionRegistryPostProcessor {
  private static final String APP_CLIENT_BEAN_NAME = "appClient_";
  private List<AppClient> clients;

  public AppClientPostProcessor(Environment environment) {
    Binder binder = Binder.get(environment);
    Bindable<List<HashMap>> target = Bindable.listOf(HashMap.class);
    List<HashMap> properties = binder.bind("pack.app.clients", target).get();
    clients = properties.stream()
        .map(c -> new AppClient(
            String.valueOf(c.get("name")),
            String.valueOf(c.get("url")),
            String.valueOf(c.get("appId")),
            String.valueOf(c.get("appKey"))))
        .toList();
  }

  @Override
  public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
    clients.forEach(client -> {
      BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(AppClient.class);
      builder.addPropertyValue("name", client.getName());
      builder.addPropertyValue("url", client.getUrl());
      builder.addPropertyValue("appId", client.getAppId());
      builder.addPropertyValue("appKey", client.getAppKey());
      registry.registerBeanDefinition(APP_CLIENT_BEAN_NAME + client.getName(), builder.getBeanDefinition());
    });
  }
}

2.4 Register the processor

@Configuration
public class AppClientConfig {
  @Bean
  static AppClientPostProcessor appClientPostProcessor(Environment env) {
    return new AppClientPostProcessor(env);
  }
}

2.5 Test

Use a CommandLineRunner to inject the list of AppClient beans and print them.

@Component
public class AppClientRunner implements CommandLineRunner {
  private final List<AppClient> clients;
  public AppClientRunner(List<AppClient> clients) {
    this.clients = clients;
  }
  @Override
  public void run(String... args) throws Exception {
    System.err.println(clients);
  }
}

Running the application prints:

[
  AppClient [name=xxx, url=http://localhost:8081/sse, appId=s-0001, appKey=111111],
  AppClient [name=ooo, url=http://localhost:8082/sse, appId=s-0002, appKey=222222]
]

This completes dynamic bean registration based on configuration properties.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

spring-bootconfiguration-propertiesdynamic-bean-registrationBeanDefinitionRegistryPostProcessor
Spring Full-Stack Practical Cases
Written by

Spring Full-Stack Practical Cases

Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.