Могу ли я динамически загрузить дополнительные файлы конфигурации Spring в существующий WebApplicationContext? - PullRequest
7 голосов
/ 20 июня 2009

После запуска моего веб-приложения в Tomcat 6.0.18 я загружаю Spring только с тем, что необходимо для инициализации системы, а именно, на данный момент, при миграции баз данных. Я не хочу, чтобы какая-либо часть системы загружалась до тех пор, пока миграции не будут успешно завершены. Это не позволяет другим компонентам ждать завершения миграции, прежде чем работать или даже создавать ее экземпляры.

У меня есть файл startup-appcontext.xml, настроенный с помощью dbMigrationDAO, startupManager, который является ThreadPoolExecutor , и, наконец, компонентом FullSystemLauch. Я передаю список местоположений конфигурации бину FullSystemLaunch с помощью инъекции сеттера. Bean-компонент FullSystemLaunch реализует ServletContextAware , получает ссылку на текущий WebApplicationContext и, таким образом, я могу иметь ConfigurableListableBeanFactory . К сожалению, эта фабрика bean isConfigurationFrozen () возвращает true, поэтому вызов beanFactory.setConfigLocations (configLocations) не имеет никакого эффекта.

Могу ли я сделать это или Spring мешает мне сделать это, потому что это немного необычно? Это кажется разумным, если его понять, но также немного опасно. И да, я готов уничтожить текущий контекст, так как загруженные в данный момент Singletons не нужны после завершения инициализации.

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

Ответы [ 6 ]

3 голосов
/ 23 июня 2009

Мое мнение состояло бы в том, чтобы позволить Spring инициализировать ваши bean-компоненты, если они сочтут нужным - в порядке их объявленных зависимостей.

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

  • если вы используете Hibernate / JPA, сделайте ваш sessionFactory / persistenceManager зависимым от компонентов миграции;
  • если вы используете простой JDBC, создайте обёртку DataSource и в его init-методе вызовите миграции ( пример кода )

Преимущество очевидно: простота.

2 голосов
/ 21 июня 2009

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

Если вы используете упаковку EAR - WAR, вы получаете это из коробки (как бы), загружая контекст приложения из EAR, а затем добавляя его в WAR.

Не уверен, применимо ли это в вашей ситуации.

0 голосов
/ 19 сентября 2009

Была та же задача, и я создал два контекста: startUpContext.xml и applicationContext.xml. В startUpContext.xml есть компонент, который запускает загрузку appliationContext.xml. (расположение контекста приложения настраивается в startUpContext.xml как свойство триггера). И, наконец, триггер заменяет местоположения текущего контекста и обновляет его:

applicationContext.setConfigLocations(locations);
applicationContext.refresh();

(файл startUpContext.xml загружается со стандартным слушателем загрузчика контекста Spring)

0 голосов
/ 19 сентября 2009

вы можете загрузить WebApplicatonContext в ConfigurableWebApplicationContext затем используйте метод setConfigurations.

не забудьте обновить;

0 голосов
/ 23 июня 2009

Возможно XmlBeanDefinitionReader может вам помочь?

0 голосов
/ 22 июня 2009

Может ли ленивая инициализация быть альтернативой тому, чего вы пытаетесь достичь?

...