«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 необходимо добавить следующий раздел \u003cdependencyManagement\u003e:
<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.baeldung.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
Здесь мы можем использовать интерфейс модуля 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.baeldung.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, baeldung!";
}
@POST
public String save() {
return "Data Saved!";
}
}
Чтобы сопоставить конечные точки с собственным экземпляром Джерси Bootique, нам нужно определить JerseyModule: ~ ~~
Module module = binder -> JerseyModule
.extend(binder)
.addResource(IndexController.class);
6. Конфигурация
Мы можем предоставить встроенную или пользовательскую информацию о конфигурации в файле свойств на основе YAML.
Например, если мы хотим запустить приложение на пользовательском порту и добавить контекст URI по умолчанию «hello», мы можем использовать следующую конфигурацию YAML:
jetty:
context: /hello
connector:
port: 10001
Теперь, запуская приложение, мы необходимо указать местоположение этого файла в параметре конфигурации:
--config=/home/baeldung/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.