1. Обзор
Bootique
— это очень легкая среда JVM без контейнеров с
открытым исходным кодом, предназначенная для создания масштабируемых микросервисов следующего поколения. Он построен на основе встроенного сервера Jetty и полностью поддерживает обработчики REST с помощью
jax-rs
.
В этой статье мы покажем, как создать простое веб-приложение с помощью Bootique
.
2. Зависимости Maven
Давайте начнем использовать Bootique
, добавив следующую зависимость в pom.xml:
<dependency>
<groupId>io.bootique.jersey</groupId>
<artifactId>bootique-jersey</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.bootique</groupId>
<artifactId>bootique-test</artifactId>
<scope>test</scope>
</dependency>
Однако Bootique
также требует декларировать несколько импортируемых спецификаций («Bill of Material»)
. Вот почему в pom.xml
необходимо добавить следующий раздел <dependencyManagement> :
``
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.bootique.bom</groupId>
<artifactId>bootique-bom</artifactId>
<version>0.23</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Последняя версия Bootique
доступна в Центральном репозитории Maven .
Для создания работающего jar - файла Bootique
использует maven-shade-plugin . Вот почему нам также необходимо добавить следующую конфигурацию:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
</plugin>
</plugins>
</build>
3. Запуск приложения
Самый простой способ запустить приложение Bootique
— вызвать метод exec()
Bootique
из основного метода: ``
public class App {
public static void main(String[] args) {
Bootique.app(args)
.autoLoadModules()
.exec();
}
}
Однако это не запустит встроенный сервер. После запуска вышеуказанного кода должен отображаться следующий журнал:
NAME
com.foreach.bootique.App
OPTIONS
-c yaml_location, --config=yaml_location
Specifies YAML config location, which can be a file path
or a URL.
-h, --help
Prints this message.
-H, --help-config
Prints information about application modules and their
configuration options.
-s, --server
Starts Jetty server.
Это не что иное, как доступные программные аргументы, поставляемые вместе с Bootique
.
Имена говорят сами за себя; следовательно, чтобы запустить сервер, нам нужно передать аргумент –s
или –server
, и сервер будет запущен и работает на порту по умолчанию 8080
.
4. Модули
Приложения Bootique
состоят из наборов «модулей». В терминах Bootique
« модуль — это библиотека Java, содержащая некоторый код»
, что означает, что он рассматривает каждую службу как модуль. Он использует Google Guice
для внедрения зависимостей.
Чтобы увидеть, как это работает, давайте создадим один интерфейс:
public interface HelloService {
boolean save();
}
Теперь нам нужно создать реализацию:
public class HelloServiceImpl implements HelloService {
@Override
public boolean save() {
return true;
}
}
Есть два способа загрузки модуля. Первый — использовать интерфейс модуля
Guice
, а второй — использовать BQModuleProvider
Bootique, который
также известен как автозагрузка
.
`` ``
4.1. Модуль гида
Здесь мы можем использовать интерфейс модуля
Guice
для привязки экземпляров: ``
public class ModuleBinder implements Module {
@Override
public void configure(Binder binder) {
binder
.bind(HelloService.class)
.to(HelloServiceImpl.class);
}
}
Как только модуль определен, нам нужно сопоставить этот пользовательский модуль с экземпляром Bootique
:
Bootique
.app(args)
.module(module)
.module(ModuleBinder.class)
.autoLoadModules()
.exec();
4.2. BQModuleProvider
(автозагрузка)
Здесь все, что нам нужно сделать, это определить ранее созданный связыватель модулей с помощью BQModuleProvider
:
public class ModuleProvider implements BQModuleProvider {
@Override
public Module module() {
return new ModuleBinder();
}
}
Преимущество этого метода в том, что нам не нужно сопоставлять какую-либо информацию о модуле с экземпляром Bootique
.
Нам просто нужно создать файл в /resources/META-INF/services/io.bootique.BQModuleProvider
и написать полное имя ModuleProvider
, включая имя пакета, а Bootique
позаботится обо всем остальном:
com.foreach.bootique.module.ModuleProvider
Теперь мы можем использовать аннотацию @Inject
для использования экземпляров службы во время выполнения:
@Inject
HelloService helloService;
Здесь важно отметить одну важную вещь: поскольку мы используем собственный механизм DI Bootique
, нам не нужно использовать аннотацию Guice @ImplementedBy
для привязки экземпляров службы.
5. Конечная точка REST
Создать конечные точки REST с помощью JAX-RS API очень просто:
@Path("/")
public class IndexController {
@GET
public String index() {
return "Hello, foreach!";
}
@POST
public String save() {
return "Data Saved!";
}
}
Чтобы сопоставить конечные точки с собственным экземпляром Jersey
Bootique
, нам нужно определить JerseyModule
: [
](https://github.com/bootique/bootique-jersey/blob/master/bootique-jersey/src/main/java/io/bootique/jersey/JerseyModule.java)
Module module = binder -> JerseyModule
.extend(binder)
.addResource(IndexController.class);
6. Конфигурация
Мы можем предоставить встроенную или пользовательскую информацию о конфигурации в файле свойств на основе YAML.
Например, если мы хотим запустить приложение на пользовательском порту и добавить контекст URI по умолчанию «привет», мы можем использовать следующую конфигурацию YAML:
jetty:
context: /hello
connector:
port: 10001
Теперь при запуске приложения нам нужно указать местоположение этого файла в параметре конфигурации:
--config=/home/foreach/bootique/config.yml
7. Ведение журнала
Готовый Bootique
поставляется с модулем bootique-
logback . Чтобы использовать этот модуль, нам нужно добавить следующую зависимость в pom.xml
:
<dependency>
<groupId>io.bootique.logback</groupId>
<artifactId>bootique-logback</artifactId>
</dependency>
Этот модуль поставляется с интерфейсом BootLogger
, который мы можем переопределить для реализации пользовательского ведения журнала:
Bootique.app(args)
.module(module)
.module(ModuleBinder.class)
.bootLogger( new BootLogger() {
@Override
public void trace( Supplier<String> args ) {
// ...
}
@Override
public void stdout( String args ) {
// ...
}
@Override
public void stderr( String args, Throwable thw ) {
// ...
}
@Override
public void stderr( String args ) {
// ...
}
}).autoLoadModules().exec();
Кроме того, мы можем определить информацию о конфигурации ведения журнала в файле config.yaml
:
log:
level: warn
appenders:
- type: file
logFormat: '%c{20}: %m%n'
file: /path/to/logging/dir/logger.log
8. Тестирование
Для тестирования Bootique
поставляется с модулем bootique-test
. Есть два способа протестировать приложение Bootique
.
Первый подход — это подход «переднего плана»,
при котором все тестовые примеры выполняются в основном тестовом потоке.
Другой — «фоновый»
подход, при котором тестовые случаи выполняются в изолированном пуле потоков.
Среду переднего плана можно инициализировать с помощью BQTestFactory
:
@Rule
public BQTestFactory bqTestFactory = new BQTestFactory();
Фоновую среду можно инициализировать с помощью BQDaemonTestFactory
:
@Rule
public BQDaemonTestFactory bqDaemonTestFactory = new BQDaemonTestFactory();
Как только фабрика среды будет готова, мы можем написать простые тестовые примеры для тестирования сервисов:
@Test
public void givenService_expectBoolen() {
BQRuntime runtime = bqTestFactory
.app("--server").autoLoadModules()
.createRuntime();
HelloService service = runtime.getInstance( HelloService.class );
assertEquals( true, service.save() );
}
9. Заключение
В этой статье мы показали, как создать приложение, используя основные модули Bootique .
Доступно несколько других модулей Bootique , таких как
bootique-jooq
, bootique-kotlin
, bootique-job
и т. д. Полный список доступных модулей доступен здесь .
Как всегда, полный исходный код доступен на GitHub.