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

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

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.