dynamically declare beans at runtime in Spring

Solution 1:

The common way to have different beans in the application context is using profiles. You can read about profiles in the following spring source posts:

  • http://blog.springsource.org/2011/02/14/spring-3-1-m1-introducing-profile
  • http://blog.springsource.org/2011/06/21/spring-3-1-m2-testing-with-configuration-classes-and-profiles/

About your first question, you can declare beans at runtime via BeanDefinitionRegistry.registerBeanDefinition() method, for example:

  BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(SomeClass.class);
  builder.addPropertyReference("propertyName", "someBean");  // add dependency to other bean
  builder.addPropertyValue("propertyName", someValue);      // set property value
  DefaultListableBeanFactory factory = (DefaultListableBeanFactory) context.getBeanFactory();
  factory.registerBeanDefinition("beanName", builder.getBeanDefinition());

Is possible also to register a singleton bean instance (already configured) with

context.getBeanFactory().registerSingleton(beanName, singletonObject)

Finally, Spring don't provides a clear way to change a bean after refreshing the context, but the most common approachs are:

  • close and refresh again (obiously)
  • Use a proxy and swap the targetSource at runtime: see Replace spring bean in one context with mock version from another context (for an example).