Загрузите класс Spring @Configuration из другого модуля Maven в многомодульном проекте
Перед выпуском, я думаю, вопрос сводится к следующему:
Как я могу правильно создать экземпляр @Configuration
бины из конфигурации приложения на основе XML?
В попытке модулировать мой проект и следовать чему-то вроде чистой архитектуры, я создал проект Maven, состоящий из трех модулей. Существует модуль "web", модуль "interface" и модуль "core", и как web, так и core используют конфигурацию Spring на основе Java.
Веб-модуль объявляет в своем POM зависимость времени выполнения от основного модуля и зависимость времени компиляции от интерфейсного модуля. Базовый модуль - это реализация интерфейсного модуля, последний состоит только из интерфейсов Java и DTO. (Это попытка программирования для интерфейса модулей.)
Когда я запускаю веб-модуль, я хочу, чтобы все компоненты, управляемые Spring, из основного модуля стали известны контексту приложения веб-модуля. У меня был некоторый успех в выполнении этого "XML-пути" путем создания XML-файла в модуле ядра, который выглядит следующим образом:
// This xml snippet is part of the "core" module
<beans>
<context:annotation-config />
<context:component-scan base-package="com.acme.core"/>
</beans>
... и ссылаться на это в конфигурации веб- модуля следующим образом:
// The configuration of the "web" module
@Configuration
@ImportResource("classpath*:come/acme/configuration/spring/*.xml")
public class RootConfig {}
Это работает, но я не доволен решением, потому что я хочу, чтобы все настройки для основного модуля выполнялись в стиле Java.
Поэтому я отмечаю, что Spring говорит, что можно сделать следующее:
...
@Configuration
классы могут быть объявлены как обычные определения в файлах Spring XML:
<beans>
<context:annotation-config/>
<bean class="com.acme.configuration.spring.CoreConfig"/>
</beans>
Это было бы (почти) идеально, если бы это работало, потому что XML-файл в модуле ядра был бы очень скудным и по сути просто загружал мясистую конфигурацию в CoreConfig
, Однако это не работает для меня, и веб-модуль не может найти ни одного компонента, определенного в модуле ядра. Я думаю, что это может быть потому, что если бины создаются, то это делается в другом контексте приложения или, может быть, потому что CoreConfig
, отмеченный @Configuration
, является особенным, и создание его экземпляра таким образом из файла XML не запускает создание других bean-компонентов, которые он определяет.
Между прочим, я предпочел бы иметь способ сделать это без какой-либо конфигурации XML, но ссылки com.acme.configuration.spring.AppConfig
напрямую из веб-модуля это невозможно, так как от кода не зависит время компиляции. (Вздох) Модуляризация пока доставляет больше хлопот, чем стоит...
1 ответ
Следующее работает, когда указано в классе config модуля "Web" в моем примере:
@Configuration
@ComponentScan(basePackages={"com.acme.configuration"})
public class RootConfig {}
На самом деле это то, что @M. Дейнм сказал сделать в комментарии к вопросу. В этом примере все com.acme.configuration
пакеты, независимо от того, находятся ли они в другом модуле Maven, будут правильно подобраны и обработаны. Тогда, по соглашению, необходимо, чтобы все классы конфигурации других модулей были помещены в com.acme.configuration
, При таком подходе нет необходимости в каком-либо файле конфигурации XML для "начальной загрузки" конфигурации, как я пытался это сделать.