Динамически объявлять bean-компоненты во время выполнения весной
Мне интересно, возможно ли следующее. В целях тестирования я хочу, чтобы разные классы-макеты были объявлены в контексте приложения для разных тестов. Это приемочные испытания с использованием клиента Jersey REST. Есть ли способ динамически объявить бин во время выполнения? Есть ли в Spring API, позволяющий изменять контекст приложения после загрузки контекста?
1 ответ
Обычный способ иметь разные компоненты в контексте приложения - это использование профилей. Вы можете прочитать о профилях в следующих источниках:
- 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/
Что касается вашего первого вопроса, вы можете объявить бины во время выполнения через BeanDefinitionRegistry.registerBeanDefinition()
метод, например:
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());
Можно также зарегистрировать экземпляр одиночного компонента (уже настроенный) с
context.getBeanFactory().registerSingleton(beanName, singletonObject)
Наконец, Spring не предоставляет четкого способа изменить bean-компонент после обновления контекста, но наиболее распространенные подходы:
- закрыть и обновить (послушно)
- Используйте прокси-сервер и поменяйте местами targetSource во время выполнения: см. Раздел Замена пружинного компонента в одном контексте на фиктивную версию из другого контекста (для примера).