Перейти к основному содержимому

Введение в Бутик

· 6 мин. чтения

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.