在 Spring 运行时动态声明 bean
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15328904/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
dynamically declare beans at runtime in Spring
提问by badgerduke
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?
我想知道以下是否可能。出于测试目的,我希望在应用程序上下文中为不同的测试声明不同的模拟类。这些是使用 Jersey REST 客户端的验收测试。有没有办法在运行时动态声明 bean?Spring 是否具有允许在加载上下文后更改应用程序上下文的 API?
回答by Jose Luis Martin
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:
在应用程序上下文中使用不同 bean 的常用方法是使用配置文件。您可以在以下 spring 源帖子中阅读有关配置文件的信息:
- 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/
- 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:
关于你的第一个问题,你可以通过BeanDefinitionRegistry.registerBeanDefinition()方法在运行时声明bean ,例如:
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
也可以注册一个单例 bean 实例(已经配置)
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:
最后,Spring 没有提供明确的方法来在刷新上下文后更改 bean,但最常见的方法是:
- 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).
- 关闭并再次刷新(显然)
- 使用代理并在运行时交换 targetSource:请参阅将一个上下文中的 spring bean 替换为另一个上下文中的模拟版本(例如)。

