Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

dynamically declare beans at runtime in Spring

Tags:

spring

I am wondering if the following is possible. For testing purposes, I wish for different mock classes to be declared in the application context for different tests. These are acceptance tests, using the Jersey REST client. Is there a way to dynamically declare a bean at runtime? Does Spring have an API to allow changes to the application context after the context has been loaded?

like image 801
badgerduke Avatar asked Mar 10 '13 23:03

badgerduke


1 Answers

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).
like image 161
Jose Luis Martin Avatar answered Nov 16 '22 02:11

Jose Luis Martin