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