2013-05-17 3 views
2

В настоящее время мы имеем веб-приложение Spring и делаем нашу конфигурацию с использованием XML-файлов. Мы запускаем Spring DispatcherServlet, который создает XmlWebApplicationContext и загружает его из местоположения по умолчанию: spring-servlet.xml.Динамически загружать файл весны xml на основе значений базы данных

Я задаю несколько дополнительных файлов конфигурации, используя контекст-параметр contextConfigLocation. Это загружает все наше приложение из файлов XML.

Итак, вот что я хочу сделать. Файл XML содержит информацию о подключении к базе данных и наши DAO для доступа к этим таблицам. Я хочу использовать один из этих DAO для чтения значения из базы данных и загрузки дополнительного набора компонентов из файла XML.

Так что если полученное значение базы данных равно оранжевому, я хочу загрузить beans из orange.xml. Если это яблоко, я хочу загрузить apple.xml. Я хочу, чтобы эти компоненты были частью одного и того же контекста приложения, поэтому после их загрузки я могу двигаться вперед, не замечая разницы.

Мне интересно, должен ли я реализовать свой собственный подкласс XmlWebApplicationContext и реализовать DispatcherServlet, но я не совсем уверен, как это сделать.

+1

Возможно, дубликат. Помогает ли это: http://stackoverflow.com/questions/3035630/how-to-achieve-conditional-resource-import-in-a-spring-xml-context – happybuddha

+0

Я так не думаю. Морщина заключается в том, что мне нужно загрузить часть компонентов, а затем, используя один из этих компонентов, загрузите остальную часть компонентов из нового XML-файла, указанного на лету. – Thom

ответ

0

Мы закончили расширение XmlWebApplicationContext и переопределение метода loadBeans. Мы загружаем бобы, просматриваем компонент, который предоставляет нашу конфигурацию, затем переключаем профили и снова запускаем новые профили.

Спасибо за помощь.

5

Непосредственная загрузка из разных файлов, но вы можете попробовать использовать Spring Environment и Profile abstractions.

<beans profile="apple"> 
    <bean id="someBean"> 
     ...first set of bean parameters... 
    </bean> 
</beans> 
<beans profile="orange"> 
    <bean id="someBean"> 
     ...second set of bean parameters... 
    </bean> 
</beans> 

И в Java:

context.getEnvironment().setActiveProfiles("orange"); 
context.refresh(); 
+0

Ничего себе! Это круто. Я прочитаю об этом. – Thom

+0

Если вы можете решить, что оранжевый - хороший профиль перед обновлением(), то вы можете добавить непосредственно расположение конфигурации orange.xml и профили вообще не нужны. –

1

Вы можете использовать BeanFactoryPostProcessor для загрузки конфигурации.

Например, если у вас есть LocationService, которые дают места конфигурации как String []:

public class XmlBeanDefinitionReaderPostProcessor implements BeanFactoryPostProcessor { 

    @Override 
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { 

     XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader((BeanDefinitionRegistry) beanFactory); 
     ResourceLoader resourceLoader = new DefaultResourceLoader(); 
     reader.setResourceLoader(new DefaultResourceLoader()); 
     reader.setEntityResolver(new ResourceEntityResolver(resourceLoader)); 
     reader.setEnvironment(new StandardEnvironment()); 
     LocationService locationService = (LocationService) beanFactory.getBean("locationService"); 

     reader.loadBeanDefinitions(locationService.getLocations());  
    } 

} 

не точно такой же, как читатель не знает о уже загруженных бобов и может быть псевдонимами или боб имена колоний.

Обратите внимание, что ваш LocationService не должны использовать Autorwire, AOP Transactional Proxies, и то, что в целом предполагает использование BeanPostProcessors.

Другой вариант для повторного использования того же XmlBeanDefinitionReader является переопределение postProcessBeanFactory метод в XmlWebApplicationContext:

public class CustomWebApplicationContext extends XmlWebApplicationContext { 

    private XmlBeanDefinitionReader reader; 

    @Override 
    protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws IOException { 
     this.reader = reader; 
     super.loadBeanDefinitions(reader); 
    } 

    @Override 
    protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { 
     LocationService locationService = (LocationService) beanFactory.getBean("locationService"); 
     this.reader.loadBeanDefinitions(locationService.getLocations()); 

     super.postProcessBeanFactory(beanFactory); 
    } 

} 
Смежные вопросы