Introdução aos Spring Boot Starters

Introdução aos Spring Boot Starters

1. Visão geral

O gerenciamento de dependências é um aspecto crítico de qualquer projeto complexo. E fazer isso manualmente é menos que o ideal; quanto mais tempo você gasta nele, menos tempo tem nos outros aspectos importantes do projeto.

Os iniciantes do Spring Boot foram criados para solucionar exatamente esse problema. As POMs iniciais são um conjunto de descritores de dependência convenientes que você pode incluir em seu aplicativo. Você obtém um balcão único para toda a tecnologia Spring e relacionada de que precisa, sem precisar procurar o código de exemplo e copiar e colar cargas de descritores de dependência.

Temos mais de 30 inicializadores de inicialização disponíveis - vamos ver alguns deles nas seções a seguir.

2. The Web Starter

Primeiro, vamos dar uma olhada no desenvolvimento do serviço REST; podemos usar bibliotecas como Spring MVC, Tomcat e Jackson - muitas dependências para um único aplicativo.

Os iniciantes do Spring Boot podem ajudar a reduzir o número de dependências adicionadas manualmente adicionando apenas uma dependência. Portanto, em vez de especificar manualmente as dependências, basta adicionar um iniciador como no exemplo a seguir:


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

Agora podemos criar um controlador REST. Por questões de simplicidade, não usaremos o banco de dados e nos concentraremos no controlador 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();
    }
}

OGenericEntity é um bean simples comid do tipoLongevalue do tipoString.

É isso - com o aplicativo em execução, você pode acessarhttp://localhost:8080/entity/alle verificar se o controlador está funcionando.

Criamos um aplicativo REST com uma configuração mínima.

3. O Test Starter

Para testes, geralmente usamos o seguinte conjunto de bibliotecas: Spring Test, JUnit, Hamcrest e Mockito. Podemos incluir todas essas bibliotecas manualmente, mas o iniciador do Spring Boot pode ser usado para incluir automaticamente essas bibliotecas da seguinte maneira:


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

Observe que você não precisa especificar o número da versão de um artefato. O Spring Boot descobrirá qual versão usar - tudo que você precisa especificar é a versão do artefatospring-boot-starter-parent. Se, posteriormente, você precisar atualizar a biblioteca de inicialização e as dependências, basta atualizar a versão de inicialização em um único local e ele cuidará do resto.

Vamos testar o controlador que criamos no exemplo anterior.

Existem duas maneiras de testar o controlador:

  • Usando o ambiente simulado

  • Usando o contêiner Servlet incorporado (como Tomcat ou Jetty)

Neste exemplo, usaremos um ambiente simulado:

@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)));
    }
}

O teste acima chama o endpoint/entity/all e verifica se a resposta JSON contém 4 elementos. Para que esse teste seja aprovado, também precisamos inicializar nossa lista na classe controller:

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"));
    }
    //...
}

O que é importante aqui é que a anotação@WebAppConfiguration eMockMVC fazem parte do módulospring-test,hasSize é um matcher Hamcrest e@Before é uma anotação JUnit. Todos estão disponíveis importando uma dependência inicial deste.

4. O Data JPA Starter

A maioria dos aplicativos da web tem algum tipo de persistência - e isso geralmente é JPA.

Em vez de definir todas as dependências associadas manualmente - vamos com o iniciador:


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


    com.h2database
    h2
    runtime

Observe que, fora da caixa, temos suporte automático para pelo menos os seguintes bancos de dados: H2, Derby e Hsqldb. Em nosso exemplo, usaremos H2.

Agora vamos criar o repositório para nossa entidade:

public interface GenericEntityRepository extends JpaRepository {}

Hora de testar o código. Aqui está o teste 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());
    }
}

Não perdemos tempo especificando o fornecedor do banco de dados, a conexão do URL e as credenciais. Nenhuma configuração extra é necessária, pois estamos nos beneficiando dos sólidos padrões de inicialização; mas é claro que todos esses detalhes ainda podem ser configurados, se necessário.

5. The Mail Starter

Uma tarefa muito comum no desenvolvimento corporativo é enviar email, e lidar diretamente com a Java Mail API geralmente pode ser difícil.

O iniciador do Spring Boot oculta essa complexidade - as dependências de email podem ser especificadas da seguinte maneira:


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

Agora podemos usar diretamente oJavaMailSender, então vamos escrever alguns testes.

Para fins de teste, precisamos de um servidor SMTP simples. Neste exemplo, usaremos Wiser. É assim que podemos incluí-lo em nosso POM:


    org.subethamail
    subethasmtp
    3.1.7
    test

A última versão do Wiser pode ser encontrada emMaven central repository.

Aqui está o código fonte do teste:

@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;
    }
}

No teste, os métodos@Beforee@After são responsáveis ​​por iniciar e parar o servidor de correio.

Observe que estamos conectando no beanJavaMailSender - o bean eraautomatically created by Spring Boot.

Assim como qualquer outro padrão no Boot, as configurações de e-mail paraJavaMailSender podem ser personalizadas emapplication.properties:

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

Portanto, configuramos o servidor de e-mail emlocalhost:25e não exigimos autenticação.

6. Conclusão

Neste artigo, fornecemos uma visão geral do Starters, explicamos por que precisamos deles e fornecemos exemplos de como usá-los em seus projetos.

Vamos recapitular os benefícios do uso de iniciadores Spring Boot:

  • aumentar a gerenciabilidade do pom

  • configurações de dependência prontas para produção, testadas e suportadas

  • diminuir o tempo de configuração geral do projeto

A lista real de iniciadores pode ser encontradahere. O código-fonte dos exemplos pode ser encontradohere.