Долгое время в спецификации Java EE отсутствовал API пакетной обработки. Сегодня это крайне необходимо для корпоративных приложений. Наконец, это было исправлено с помощью пакетных приложений JSR-352 для платформы Java, которые теперь доступны в Java EE 7. JSR-352 получил вдохновение от аналога Spring Batch . Оба охватывают одни и те же понятия, хотя получающиеся API немного отличаются.
Поскольку команда Spring также сотрудничала в JSR-352 , для них было только вопросом времени предоставить реализацию, основанную на Spring Batch . Последняя основная версия Spring Batch (версия 3) теперь поддерживает JSR-352 .
Я много лет пользуюсь Spring Batch, и мне всегда нравилось, что у этой технологии был интересный набор встроенных читателей и писателей. Это позволило вам выполнять самые распространенные операции, необходимые для пакетной обработки. Вам нужно читать данные из базы данных? Вы можете использовать JdbcCursorItemReader
, как насчет записи данных в фиксированном формате? Используйте FlatFileItemWriter
и так далее.
К сожалению, реализации JSR-352 не имеют такого количества читателей и писателей, которые доступны в Spring Batch . Мы должны помнить, что JSR-352 появился совсем недавно и не успел наверстать упущенное. jBeret , реализация Wildfly для JSR-352 уже предоставляет несколько пользовательских программ для чтения и записи.
В чем смысл?
Я надеялся, что с последним выпуском все читатели и писатели из оригинальной Spring Batch также будут доступны. Это еще не так, поскольку потребуется много работы, но есть планы сделать их доступными в будущих версиях. Это позволило бы нам перенести собственные приложения Spring Batch в JSR-352 . У нас все еще есть проблема блокировки реализации реализации, но в некоторых случаях это может быть интересно.
мотивация
Я являюсь одним из основных разработчиков тестов для примеров Java EE в спецификации JSR-352 . Я хотел выяснить, имеют ли тесты, которые я реализовал, то же самое поведение, используя реализацию Spring Batch . Как мы можем сделать это?
Код
Я думаю, что это упражнение не только интересно из-за оригинальной мотивации, но также полезно узнать о модулях и загрузке классов в Wildfly . Сначала нам нужно решить, как мы будем развертывать необходимые зависимости Spring Batch . Мы могли бы развернуть их напрямую с приложением или использовать модуль Wildfly . Преимущество модулей заключается в том, что они могут быть встроены непосредственно в сервер приложений и могут использоваться всеми развернутыми приложениями.
Добавление модуля Wildfly с Maven
Немного поработав, можно автоматически добавить модуль с помощью плагина Wildfly Maven и CLI (командной строки). Давайте начнем создавать два файла, которые представляют команды CLI, которые нам нужны для создания и удаления модуля:
wildfly-add-spring-batch.cli
wildfly-надстройка весна-batch.cli
1
2
3
4
5
6
7
8
9
|
# Connect to Wildfly instance connect # Create Spring Batch Module # If the module already exists, Wildfly will output a message saying that the module already exists and the script exits. module add \ --name=org.springframework.batch \ --dependencies=javax.api,javaee.api \ --resources=${wildfly.module.classpath} |
Модуль --name
важен. Нам понадобится ссылка для ссылки в нашем приложении. --resources
— --resources
, так как вам нужно указать полный путь к классу для всех необходимых зависимостей модуля, но мы создадим пути в следующих нескольких шагах.
wildfly-remove-spring-batch.cli
wildfly-удалить-весенне-batch.cli
1
2
3
4
5
|
# Connect to Wildfly instance connect # Remove Oracle JDBC Driver Module module remove --name=org.springframework.batch |
Обратите внимание на wildfly.module.classpath
. Это свойство будет содержать полный путь к классу для необходимых зависимостей Spring Batch . Мы можем сгенерировать его с помощью плагина Maven Dependency :
П-Maven-зависимость-plugin.xml
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
|
< plugin > < groupId >org.apache.maven.plugins</ groupId > < artifactId >maven-dependency-plugin</ artifactId > < version >${version.plugin.dependency}</ version > < executions > < execution > < phase >generate-sources</ phase > < goals > < goal >build-classpath</ goal > </ goals > < configuration > < outputProperty >wildfly.module.classpath</ outputProperty > < pathSeparator >:</ pathSeparator > < excludeGroupIds >javax</ excludeGroupIds > < excludeScope >test</ excludeScope > < includeScope >provided</ includeScope > </ configuration > </ execution > </ executions > </ plugin > |
Это javax
выбрать все зависимости (включая транзитивные), исключить javax
(поскольку они уже присутствуют в Wildfly ) и исключить зависимости области test
. Нам нужны следующие зависимости для Spring Batch :
П-dependencies.xml
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
<!-- Needed for Wildfly module --> < dependency > < groupId >org.springframework.batch</ groupId > < artifactId >spring-batch-core</ artifactId > < version >3.0.0.RELEASE</ version > < scope >provided</ scope > </ dependency > < dependency > < groupId >org.springframework</ groupId > < artifactId >spring-jdbc</ artifactId > < version >4.0.5.RELEASE</ version > < scope >provided</ scope > </ dependency > < dependency > < groupId >commons-dbcp</ groupId > < artifactId >commons-dbcp</ artifactId > < version >1.4</ version > < scope >provided</ scope > </ dependency > < dependency > < groupId >org.hsqldb</ groupId > < artifactId >hsqldb</ artifactId > < version >2.3.2</ version > < scope >provided</ scope > </ dependency > |
Теперь нам нужно заменить свойство в файле. Давайте использовать плагин Maven Resources :
П-Maven-ресурсы-plugin.xml
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
< plugin > < groupId >org.apache.maven.plugins</ groupId > < artifactId >maven-resources-plugin</ artifactId > < version >${version.plugin.resources}</ version > < executions > < execution > < id >copy-resources</ id > < phase >process-resources</ phase > < goals > < goal >copy-resources</ goal > </ goals > < configuration > < outputDirectory >${basedir}/target/scripts</ outputDirectory > < resources > < resource > < directory >src/main/resources/scripts</ directory > < filtering >true</ filtering > </ resource > </ resources > </ configuration > </ execution > </ executions > </ plugin > |
Это отфильтрует настроенные файлы и заменит свойство wildfly.module.classpath
на значение, которое мы сгенерировали ранее. Это путь к классу, указывающий на зависимости в вашем локальном репозитории Maven. Теперь с плагином Wildfly Maven мы можем выполнить этот скрипт (вам нужно запустить Wildfly ):
ПОМ-Maven-wildfly-plugin.xml
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
< plugin > < groupId >org.wildfly.plugins</ groupId > < artifactId >wildfly-maven-plugin</ artifactId > < version >${version.plugin.wildfly}</ version > < configuration > < skip >false</ skip > < executeCommands > < batch >false</ batch > < scripts > <!--suppress MavenModelInspection --> < script >target/scripts/${cli.file}</ script > </ scripts > </ executeCommands > </ configuration > </ plugin > |
И эти профили:
П-profiles.xml
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
< profiles > < profile > < id >install-spring-batch</ id > < properties > < cli.file >wildfly-add-spring-batch.cli</ cli.file > </ properties > </ profile > < profile > < id >remove-spring-batch</ id > < properties > < cli.file >wildfly-remove-spring-batch.cli</ cli.file > </ properties > </ profile > </ profiles > |
(Для полного содержания pom.xml
, проверьте здесь )
Мы можем добавить модуль, выполнив:
mvn process-resources wildfly:execute-commands -P install-spring-batch
.
Или удалите модуль, выполнив:
mvn wildfly:execute-commands -P remove-spring-batch
.
Эта стратегия работает для любого модуля, который вы хотите создать в Wildfly . Подумайте о добавлении драйвера JDBC. Обычно вы используете модуль для добавления его на сервер, но вся документация, которую я нашел по этому поводу, всегда выполняется вручную. Это прекрасно работает для сборок CI, поэтому вы можете иметь все необходимое для настройки вашей среды.
Использовать Spring-Batch
Хорошо, у меня есть мой модуль, но как я могу проинструктировать Wildfly использовать его вместо jBeret ? Нам нужно добавить следующий файл в папку META-INF
нашего приложения:
jboss-deployment-structure.xml
JBoss развертывания-structure.xml
01
02
03
04
05
06
07
08
09
10
11
12
13
|
<? xml version = "1.0" encoding = "UTF-8" ?> < jboss-deployment-structure > < deployment > < exclusions > < module name = "org.wildfly.jberet" /> < module name = "org.jberet.jberet-core" /> </ exclusions > < dependencies > < module name = "org.springframework.batch" services = "import" meta-inf = "import" /> </ dependencies > </ deployment > </ jboss-deployment-structure > |
Поскольку JSR-352 использует загрузчик служб для загрузки реализации, единственным возможным результатом будет загрузка службы, указанной в модуле org.springframework.batch
. Ваш пакетный код теперь будет работать с реализацией Spring Batch .
тестирование
Код репозитория github содержит примеры тестов Arquillian , демонстрирующие поведение. Проверьте раздел Ресурсы ниже.
Ресурсы
Вы можете клонировать полную рабочую копию из моего репозитория github. Вы можете найти там инструкции по его развертыванию.
Поскольку я могу изменить код в будущем, вы можете скачать исходный код этого поста с версии 1.0 . В качестве альтернативы клонируйте репозиторий и извлеките тег из выпуска 1.0 с помощью следующей команды: git checkout 1.0
.
Будущее
Мне все еще нужно применить это к образцам Java EE . Это в моем списке TODO.
Ссылка: | Spring Batch as Wildfly Module от нашего партнера JCG Роберто Кортеса в блоге |