Загрузите класс Spring @Configuration из другого модуля Maven в многомодульном проекте.

Прежде чем начать разговор, я думаю, что вопрос, по сути, сводится к следующему:

Как правильно создать экземпляр @Configuration bean-компонентов из XML-конфигурации приложения?

В попытке разделить мой проект на модули и следовать чему-то вроде чистая архитектура, я создал проект Maven, состоящий из трех модулей. Существует «веб-модуль», «интерфейсный» модуль и «основной» модуль, и как веб-модуль, так и ядро ​​​​используют конфигурацию Spring на основе Java.

Структура и упаковка модуля

Веб-модуль объявляет в своем POM зависимость времени выполнения от основного модуля и зависимость времени компиляции от модуля интерфейса. Основной модуль — это реализация интерфейсного модуля, последний состоит только из интерфейсов Java и DTO. (Это попытка программа для интерфейса модулей.)

Когда я запускаю веб-модуль, я хочу, чтобы все bean-компоненты, управляемые Spring, из основного модуля стали известны контексту приложения веб-модуля. Я добился некоторого успеха, используя XML-способ, создав файл XML в модуле core, который выглядит следующим образом:

// This xml snippet is part of the "core" module
<beans>
    <context:annotation-config />
    <context:component-scan base-package="com.acme.core"/>
</beans>

... и сослаться на это в конфигурации модуля web следующим образом:

// The configuration of the "web" module
@Configuration
@ImportResource("classpath*:come/acme/configuration/spring/*.xml")
public class RootConfig {}

Это работает, но я не доволен решением, потому что я хочу, чтобы вся конфигурация для основного модуля выполнялась способом Java.

Поэтому я отмечаю, что Спринг говорит, можно сделать следующее:

...@Configuration классы могут быть объявлены как обычные определения в XML-файлах Spring:

<beans>
    <context:annotation-config/>
    <bean class="com.acme.configuration.spring.CoreConfig"/>
</beans>

Это было бы (почти) идеально, если бы работало, потому что файл XML в основном модуле был бы очень скудным и, по сути, просто загружал бы мясистую конфигурацию в CoreConfig. Однако у меня это не работает, и веб-модуль не может найти ни один из компонентов, определенных в основном модуле. Я думаю, это может быть связано с тем, что если создаются экземпляры bean-компонентов, то они выполняются в другом контексте приложения, или, может быть, потому, что CoreConfig, отмеченный @Configuration, является особенным, и его создание таким образом из XML-файла не не инициировать создание других компонентов, которые он определяет.

Между прочим, я предпочел бы иметь способ сделать это без какой-либо конфигурации XML, но ссылка на com.acme.configuration.spring.AppConfig непосредственно из веб-модуля невозможна, поскольку код не зависит от времени компиляции. (Вздыхает) Модульность до сих пор доставляет больше проблем, чем пользы...


person chrisjleu    schedule 05.06.2014    source источник
comment
Добавьте классы @Configuration в свои проекты в Интернете, выполните сканирование компонентов для com.acme.configuration, это подберет все классы @Configuration (если они есть). Или поместите свои xml-файлы в хорошо известное место (например, /META-INF/spring) и в yuor web.xml сделайте classpath*:/META-INF/spring/*.xml, чтобы получить все файлы конфигурации xml.   -  person M. Deinum    schedule 05.06.2014
comment
Это не так просто... получение XML-файла основного модуля в любом случае не является проблемой; веб-модуль отлично находит XML-файл основного модуля, но я не знаю, соблюдается ли аннотация @Configuration в bean-компоненте CoreConfig. Создан экземпляр CoreConfig, но для создания экземпляров bean-компонентов, перечисленных в CoreConfig, и любых других его аннотаций, которые выполняют важные функции, должно произойти нечто большее.   -  person chrisjleu    schedule 05.06.2014


Ответы (1)


Следующее работает, если указано в классе конфигурации модуля «Web» в моем примере:

@Configuration
@ComponentScan(basePackages={"com.acme.configuration"})
public class RootConfig {}

На самом деле, это то, что @M. Дейнум сказал это сделать в комментарии к вопросу. В этом примере все пакеты com.acme.configuration, независимо от того, могут ли они находиться в другом модуле Maven, будут подобраны и обработаны правильно. Тогда по соглашению необходимо, чтобы все классы конфигурации других модулей были помещены в com.acme.configuration. При таком подходе нет необходимости в каком-либо файле конфигурации XML для «загрузки» конфигурации, как я пытался сделать.

person chrisjleu    schedule 27.06.2014