Введение в бутик
1. обзор
Bootique - это очень легкая платформа JVMcontainer-less с открытым исходным кодом, предназначенная для создания масштабируемых микросервисов следующего поколения. Он построен на основе встроенного сервера Jetty и полностью поддерживает обработчикиREST сjax-rs.
В этой статье мы покажем, как создать простое веб-приложение с помощьюBootique.
2. Maven Зависимости
Давайте начнем использоватьBootique, добавив следующую зависимость вpom.xml:
io.bootique.jersey
bootique-jersey
compile
io.bootique
bootique-test
test
ОднакоBootique также требует декларирования импорта несколькихBOM (“Bill of Material”). Вот почему следующий раздел<dependencyManagement> необходимо добавить вpom.xml:
io.bootique.bom
bootique-bom
0.23
pom
import
Последняя версияBootique доступна вCentral Maven Repository.
Чтобы создать работающий jar,Bootique полагается наmaven-shade-plugin. Вот почему нам также необходимо добавить следующие настройки:
org.apache.maven.plugins
maven-shade-plugin
3. Запуск приложения
Самый простой способ запустить приложениеBootique - вызвать методBootique‘sexec() из основного метода:
public class App {
public static void main(String[] args) {
Bootique.app(args)
.autoLoadModules()
.exec();
}
}
However, this won’t start the embedded server. После выполнения вышеуказанного кода должен отображаться следующий журнал:
NAME
com.example.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, и сервер будет запущен и будет работать наdefault port 8080.
4. Модули
ПриложенияBootique состоят из наборов «модулей». ВBootique термин“A module is a Java library that contains some code” означает, что он обрабатывает каждую службу как модуль. Он используетGoogle Guice для внедрения зависимостей.
Чтобы увидеть, как это работает, давайте создадим один интерфейс:
public interface HelloService {
boolean save();
}
Теперь нам нужно создать реализацию:
public class HelloServiceImpl implements HelloService {
@Override
public boolean save() {
return true;
}
}
Есть два способа загрузки модуля. Первый - использовать интерфейсGuice‘sModule, а второй - использоватьBootique ’sBQModuleProvider, который также известен какauto-loading.
4.1. Модуль Guice
Здесь мы можем использовать интерфейсGuice ’sModule для привязки экземпляров:
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.example.bootique.module.ModuleProvider
Теперь мы можем использовать аннотацию@Inject для использования экземпляров службы во время выполнения:
@Inject
HelloService helloService;
Здесь важно отметить, что, поскольку мы используем собственный механизм DIBootique, нам не нужно использовать аннотациюGuice @ImplementedBy для привязки экземпляров службы.
5. Конечная точка REST
Создать конечные точки REST с помощью JAX-RS API несложно:
@Path("/")
public class IndexController {
@GET
public String index() {
return "Hello, example!";
}
@POST
public String save() {
return "Data Saved!";
}
}
Чтобы сопоставить конечные точки с собственным экземпляромJerseyBootique, нам нужно определитьJerseyModule:
Module module = binder -> JerseyModule
.extend(binder)
.addResource(IndexController.class);
6. конфигурация
Мы можем предоставить встроенную или пользовательскую информацию о конфигурации в файле свойств на основе YAML.
Например, если мы хотим запустить приложение на пользовательском порту и добавить контекст URI по умолчанию «привет», мы можем использовать следующую конфигурацию YAML:
jetty:
context: /hello
connector:
port: 10001
Теперь при запуске приложения нам нужно указать расположение этого файла в параметре конфигурации:
--config=/home/example/bootique/config.yml
7. логирование
Bootique из коробки поставляется с модулемbootique-logback. Чтобы использовать этот модуль, нам нужно добавить следующую зависимость вpom.xml:
io.bootique.logback
bootique-logback
Этот модуль поставляется с интерфейсомBootLogger, который мы можем переопределить для реализации пользовательского ведения журнала:
Bootique.app(args)
.module(module)
.module(ModuleBinder.class)
.bootLogger( new BootLogger() {
@Override
public void trace( Supplier 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.
Первый подход - это подход‘foreground', при котором все тестовые примеры запускаются в основном тестовом потоке.
Другой - подход‘background', при котором тестовые примеры запускаются в изолированном пуле потоков.
Среду «переднего плана» можно инициализировать с помощью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 и т. Д. Полный список доступных модулей доступенhere.
Как всегда, доступен полный исходный кодover on GitHub.