Введение в Spring Boot Starters

Введение в Spring Boot Starters

1. обзор

Управление зависимостями является критическим аспектом любого сложного проекта. И делать это вручную не идеально; чем больше времени вы потратили на это, тем меньше времени вы уделяете другим важным аспектам проекта.

Стартеры Spring Boot были созданы именно для решения этой проблемы. Начальные POM - это набор удобных дескрипторов зависимостей, которые вы можете включить в свое приложение. Вы получаете универсальное решение для всех необходимых вам Spring и связанных с ними технологий, без необходимости искать примеры кода и копировать и вставлять множество дескрипторов зависимостей.

У нас доступно более 30 стартеров загрузки - давайте рассмотрим некоторые из них в следующих разделах.

2. Веб-стартер

Во-первых, давайте посмотрим на разработку службы REST; мы можем использовать такие библиотеки, как Spring MVC, Tomcat и Jackson - множество зависимостей для одного приложения.

Пускатели Spring Boot могут помочь уменьшить количество добавляемых вручную зависимостей, просто добавив одну зависимость. Поэтому вместо того, чтобы вручную указывать зависимости, просто добавьте один стартер, как в следующем примере:


    org.springframework.boot
    spring-boot-starter-web

Теперь мы можем создать REST-контроллер. Для простоты мы не будем использовать базу данных и сосредоточимся на контроллере REST:

@RestController
public class GenericEntityController {
    private List entityList = new ArrayList<>();

    @RequestMapping("/entity/all")
    public List findAll() {
        return entityList;
    }

    @RequestMapping(value = "/entity", method = RequestMethod.POST)
    public GenericEntity addEntity(GenericEntity entity) {
        entityList.add(entity);
        return entity;
    }

    @RequestMapping("/entity/findby/{id}")
    public GenericEntity findById(@PathVariable Long id) {
        return entityList.stream().
                 filter(entity -> entity.getId().equals(id)).
                   findFirst().get();
    }
}

GenericEntity - это простой bean-компонент сid типаLong иvalue типаString.

Вот и все - с запущенным приложением вы можете получить доступ кhttp://localhost:8080/entity/all и проверить, работает ли контроллер.

Мы создали REST-приложение с минимальной конфигурацией.

3. Тестовый стартер

Для тестирования мы обычно используем следующий набор библиотек: Spring Test, JUnit, Hamcrest и Mockito. Мы можем включить все эти библиотеки вручную, но можно использовать Spring Boot для автоматического включения этих библиотек следующим образом:


    org.springframework.boot
    spring-boot-starter-test
    test

Обратите внимание, что вам не нужно указывать номер версии артефакта. Spring Boot определит, какую версию использовать - все, что вам нужно указать, это версия артефактаspring-boot-starter-parent. Если в дальнейшем вам потребуется обновить библиотеку загрузки и зависимости, просто обновите версию загрузки в одном месте, а об остальном она позаботится.

Давайте фактически протестируем контроллер, который мы создали в предыдущем примере.

Есть два способа проверить контроллер:

  • Использование фиктивной среды

  • Использование встроенного контейнера сервлетов (например, Tomcat или Jetty)

В этом примере мы будем использовать фиктивную среду:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
public class SpringBootApplicationIntegrationTest {
    @Autowired
    private WebApplicationContext webApplicationContext;
    private MockMvc mockMvc;

    @Before
    public void setupMockMvc() {
        mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
    }

    @Test
    public void givenRequestHasBeenMade_whenMeetsAllOfGivenConditions_thenCorrect()
      throws Exception {
        MediaType contentType = new MediaType(MediaType.APPLICATION_JSON.getType(),
        MediaType.APPLICATION_JSON.getSubtype(), Charset.forName("utf8"));
        mockMvc.perform(MockMvcRequestBuilders.get("/entity/all")).
        andExpect(MockMvcResultMatchers.status().isOk()).
        andExpect(MockMvcResultMatchers.content().contentType(contentType)).
        andExpect(jsonPath("$", hasSize(4)));
    }
}

Приведенный выше тест вызывает конечную точку/entity/all и проверяет, что ответ JSON содержит 4 элемента. Чтобы пройти этот тест, мы также должны инициализировать наш список в классе контроллера:

public class GenericEntityController {
    private List entityList = new ArrayList<>();

    {
        entityList.add(new GenericEntity(1l, "entity_1"));
        entityList.add(new GenericEntity(2l, "entity_2"));
        entityList.add(new GenericEntity(3l, "entity_3"));
        entityList.add(new GenericEntity(4l, "entity_4"));
    }
    //...
}

Здесь важно то, что аннотация@WebAppConfiguration иMockMVC являются частью модуляspring-test,hasSize - сопоставитель Hamcrest, а@Before - аннотация JUnit. Все это доступно путем импорта одной этой начальной зависимости.

4. Стартер Data JPA

У большинства веб-приложений есть своего рода постоянство - и это довольно часто JPA.

Вместо того, чтобы определять все связанные зависимости вручную, давайте возьмем стартер:


    org.springframework.boot
    spring-boot-starter-data-jpa


    com.h2database
    h2
    runtime

Обратите внимание, что из коробки у нас есть автоматическая поддержка по крайней мере для следующих баз данных: H2, Derby и Hsqldb. В нашем примере мы будем использовать H2.

Теперь давайте создадим репозиторий для нашей сущности:

public interface GenericEntityRepository extends JpaRepository {}

Время проверить код. Вот тест JUnit:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
public class SpringBootJPATest {

    @Autowired
    private GenericEntityRepository genericEntityRepository;

    @Test
    public void givenGenericEntityRepository_whenSaveAndRetreiveEntity_thenOK() {
        GenericEntity genericEntity =
          genericEntityRepository.save(new GenericEntity("test"));
        GenericEntity foundedEntity =
          genericEntityRepository.findOne(genericEntity.getId());

        assertNotNull(foundedEntity);
        assertEquals(genericEntity.getValue(), foundedEntity.getValue());
    }
}

Мы не стали тратить время на указание поставщика базы данных, URL-адреса и учетных данных. Никакой дополнительной настройки не требуется, поскольку мы пользуемся надежными настройками загрузки по умолчанию; но, конечно, все эти детали можно настроить при необходимости.

5. Почтовый стартер

Очень распространенная задача в корпоративной разработке - отправка электронной почты, и работа с Java Mail API напрямую может быть затруднена.

Spring Boot starter скрывает эту сложность - почтовые зависимости можно указать следующим образом:


    org.springframework.boot
    spring-boot-starter-mail

Теперь мы можем напрямую использоватьJavaMailSender, поэтому давайте напишем несколько тестов.

Для тестирования нам нужен простой SMTP-сервер. В этом примере мы будем использовать Wiser. Вот как мы можем включить его в нашу POM:


    org.subethamail
    subethasmtp
    3.1.7
    test

Последнюю версию Wiser можно найти наMaven central repository.

Вот исходный код для теста:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
public class SpringBootMailTest {
    @Autowired
    private JavaMailSender javaMailSender;

    private Wiser wiser;

    private String userTo = "[email protected]";
    private String userFrom = "[email protected]";
    private String subject = "Test subject";
    private String textMail = "Text subject mail";

    @Before
    public void setUp() throws Exception {
        final int TEST_PORT = 25;
        wiser = new Wiser(TEST_PORT);
        wiser.start();
    }

    @After
    public void tearDown() throws Exception {
        wiser.stop();
    }

    @Test
    public void givenMail_whenSendAndReceived_thenCorrect() throws Exception {
        SimpleMailMessage message = composeEmailMessage();
        javaMailSender.send(message);
        List messages = wiser.getMessages();

        assertThat(messages, hasSize(1));
        WiserMessage wiserMessage = messages.get(0);
        assertEquals(userFrom, wiserMessage.getEnvelopeSender());
        assertEquals(userTo, wiserMessage.getEnvelopeReceiver());
        assertEquals(subject, getSubject(wiserMessage));
        assertEquals(textMail, getMessage(wiserMessage));
    }

    private String getMessage(WiserMessage wiserMessage)
      throws MessagingException, IOException {
        return wiserMessage.getMimeMessage().getContent().toString().trim();
    }

    private String getSubject(WiserMessage wiserMessage) throws MessagingException {
        return wiserMessage.getMimeMessage().getSubject();
    }

    private SimpleMailMessage composeEmailMessage() {
        SimpleMailMessage mailMessage = new SimpleMailMessage();
        mailMessage.setTo(userTo);
        mailMessage.setReplyTo(userFrom);
        mailMessage.setFrom(userFrom);
        mailMessage.setSubject(subject);
        mailMessage.setText(textMail);
        return mailMessage;
    }
}

В этом тесте методы@Before и@After отвечают за запуск и остановку почтового сервера.

Обратите внимание, что мы подключаемся к bean-компонентуJavaMailSender - bean-компонент былautomatically created by Spring Boot.

Как и любые другие значения по умолчанию в Boot, настройки электронной почты дляJavaMailSender можно настроить вapplication.properties:

spring.mail.host=localhost
spring.mail.port=25
spring.mail.properties.mail.smtp.auth=false

Итак, мы настроили почтовый сервер наlocalhost:25, и нам не требовалась аутентификация.

6. Заключение

В этой статье мы дали обзор Starters, объяснили, почему они нам нужны, и предоставили примеры их использования в ваших проектах.

Подведем итоги преимуществ использования стартеров Spring Boot:

  • повысить управляемость пом

  • готовые к тестированию и поддерживаемые конфигурации зависимостей

  • уменьшить общее время настройки проекта

Актуальный список стартеров можно найти вhere. Исходный код примеров можно найти вhere.