Ответ 1
Вариант 1 (должен быть предпочтительным, поскольку это лучшая практика):
Обновите файлы конфигурации в разделе WEB-INF
и переместите общие части (к которым вы хотите получить доступ также из тестов интеграции) до src/main/resources/
. Затем напишите тестовые файлы конфигурации в src/test/resources/
(если вам нужно импортировать несколько различных файлов конфигурации из src/main
, чтобы собрать тестовый контекст, затем пропустите это и используйте @ContextConfiguration
предпочтительно).
Вариант 2 (взломать):
Используйте ссылки, например:
@ContextConfiguration("file:src/main/webapp/WEB-INF/dataSource.xml")
Вариант 3 (взломать):
Если у вас есть проект Maven, вы можете настроить maven-surefire-plugin
(используемый на этапе тестирования), чтобы объявить src/main/webapp
в качестве дополнительного элемента classpath во время выполнения теста.
Последние два параметра считаются хаками, потому что файлы под src/main/webapp
просто не должны находиться в пути к классам.
Теперь подробное объяснение:
Причина, по которой вы не можете ссылаться на эти файлы как classpath:/WEB-INF/*.xml
, заключается в том, что они действительно не относятся к пути к классам. Важно понять, как упакован ваш webapp, и что именно заканчивается в пути к классам. Предполагая структуру проекта Maven по умолчанию:
- Классы Java из
src/main/java
перейдите к/WEB-INF/classes
после компиляции. - Ресурсы из
src/main/resources
также идут в/WEB-INF/classes
. - Зависимости проекта переходят к
/WEB-INF/lib
. - Все, что у вас есть в
src/main/webapp
, идет в/
(корень пакета). Это означает, что все файлы изsrc/main/webapp/WEB-INF
идут в/WEB-INF
, конечно.
Самое главное знать, что путь к классам будет содержать только /WEB-INF/classes
и одну запись для каждой банки в /WEB-INF/lib
. Следовательно, ресурсы за пределами этих двух мест полностью невидимы для загрузчика классов. Это также верно для файлов конфигурации xml непосредственно под /WEB-INF
, поэтому ссылка classpath:/WEB-INF/dataSource.xml
никогда не будет работать.
Вы можете спросить себя, как, черт возьми, эти xml файлы конфигурации, загруженные Spring, если они недоступны из пути к классам? Ответ прост: когда вы запускаете свой webapp (в отличие от выполнения только тестов unit/integration), он запускается в контейнере Servlet, который обеспечивает доступ к ServletContext
(фактический класс из API Servlet), поэтому он использует ServletContext.getResourceAsStream()
для загрузки этих файлов. Ключом к пониманию является следующая цитата из javadoc этого метода:
Этот метод отличается от java.lang.Class.getResourceAsStream, который использует загрузчик классов. Этот метод позволяет контейнерам сервлетов предоставлять доступный ресурс сервлету из любого места без использования загрузчика классов.
Извините, это слишком длинное, но что вся история...