2014-08-27 2 views
2

У меня есть требование, чтобы определения весеннего компонента необходимо динамически загружать из «внешнего» источника. Этот внешний источник может быть некоторым типом файла, базы данных или веб-службы.Как динамически добавлять внешние определения beans в контекст Spring?

Я прочитал на BeanFactoryPostProcessor и BeanDefinitionRegistryPostProcessor классов, которые могут делать такого рода вещи, но я бегу в одну большую проблему:

Объект, который извлекает данные боб Definiton от внешнего источника сконфигурирован в качестве самого компонента (например, DatabaseBeanDefinitionProvider), поэтому его нужно будет настроить со всеми зависимостями (например, DataSource) и доступными из контекста для извлечения данных.

Я не уверен, где/когда в жизненном цикле контекста приложения Spring для этого: по существу используйте «существующие компоненты для добавления новых bean-компонентов» в контекст.

Любые идеи экспертов?

+1

Думаю, вам нужно будет динамически создавать и управлять детскими контекстами. Вы почти не можете добавлять определения bean в уже инициализированный контекст (или вам нужно «обновлять» контекст каждый раз, когда вы изменяете определения bean-компонентов). –

+0

Вы хотите, чтобы компоненты, которые вы хотите добавить динамически, реализуют известный набор интерфейсов? –

+0

@PavelHoral - загрузка этих динамических компонентов - это процесс инициализации приложения, поэтому он должен обновляться только один раз (я думаю), хотя я все еще немного не уверен, где в инициализации сделать это. – WayneC

ответ

3

Возможность использования таблицы базы данных для загрузки сохраняемых определений bean-компонентов уже реализована Spring с помощью JdbcBeanDefinitionReader. Я упомянул об этом, чтобы быть уверенным, что вы не изобретаете велосипед;). Вы также можете использовать свойство PropertiesBeanDefinitionReader, если вы хотите полагаться только на кучу свойств из простого файла.

Оба класса имеют BeanDefinitionRegistry как зависимость, ведро, где все определения bean-компонентов будут собраны во время фазы загрузки определения компонента. Реализация интерфейса BeanDefinitionRegistryPostProcessor (BDRPP) обеспечивает это очень удобным способом.

Теперь, как его запустить: В принципе, если вы придерживаетесь способа передачи данных с использованием DataSource, я бы рекомендовал вручную установить эти зависимости, это означает создание экземпляров BDRPP и зависимостей в собственной реализации ApplicationContextInitializer. Там вы можете вызвать applicationContext.addBeanFactoryPostProcessor (yourBdrpp) и загрузить все необходимые свойства для DataSource в JdbcBeanDefinitionReader.

XML также будет работать нормально, если все ваши зависимости не зависят от какой-либо замены или замены свойств. Вы должны определить их явно, например.

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> 
    <constructor-arg ref="dataSource"/> 
</bean> 

<bean class="net.bensteinert.MyBeanDefinitionRegistryPostProcessor"> 
    <constructor-arg ref="jdbcTemplate"/> 
</bean> 

Только проблема в том, что ваш DataSource не будет иметь доступа к какой-либо собственности заполнителем инфраструктуры, что является причиной, почему я склоняюсь к программному решению.

Средство в целом, не стоит беспокоиться об использовании компонентов для создания бобов. Они просто должны быть независимыми. Кстати, мощная самонастройка Java Config также является BeanDefinitionRegistryPostProcessor.

Более подробная информация о динамическом определении фасоли также можно найти здесь: How to create dynamic bean definitions in Spring

Очень хорошее введение в Spring Bean Lifecycle можно найти здесь: SpringONE 2013 Presentation by Mark Secrist

Надежда, что помогает, так долго.

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