Engatinhando em Java para a web: Spring Boot

No post anterior, finalizamos a introdução a alguns aspectos utilizados pelo Java EE para construção de aplicações web. Se você acompanhou os artigos até aqui, e achou tudo muito doloroso, você não está sozinho.

Desenvolvedores, com o passar do tempo, ansiavam por alternativas menos burocráticas para desenvolver suas soluções. E foi em 2003, seguindo essa premissa, que Rob Johnson lançava a versão 1.0 do Spring.

Antes do Boot. O que é Spring?

Como a maioria das coisas do mundo Java, a resposta para essa pergunta pode ser mais complicada do que parece.

Uma das definições da documentação oficial é a seguinte:

Spring makes programming Java quicker, easier, and safer for everybody. Spring’s focus on speed, simplicity, and productivity has made it the world's most popular Java framework.

O Spring começou como uma resposta à complexidade do J2EE. Atualmente ele deve ser compreendido como um "complemento" à mesma, ou seja, a comunidade do Spring de fato adota partes da especificação Java EE, e com isso torna possível desenvolver aplicações "enterprise" com maior facilidade.

Flexibilidade, modularização, retrocompatibilidade, uma grande e ativa comunidade, e evolução contínua (além da sua famosa Dependency Injection), fazem do Spring um dos frameworks Java mais famosos do mercado.

Logo, como tantos outros frameworks espalhados por aí, o propósito do Spring é facilitar e acelerar o desenvolvimento, provendo bibliotecas e ferramentas que te permitam focar no negócio. No entanto, quando falamos em "Spring", provavelmente estamos falando de todo o seu ecossistema.

Organograma do ecossistema Spring
Conheça a família Spring (pluralsight.com)

Chegaremos no Spring Boot, mas antes, vamos por partes, como diria aquele famoso serial killer.

O Spring Framework

A definição do Spring como plataforma pode ser utilizada para compreender o Spring como framework. Segundo a documentação oficial:

The Spring Framework provides a comprehensive programming and configuration model for modern Java-based enterprise applications - on any kind of deployment platform.

Uma de suas principais características é lidar com aspectos de aplicações enterprise, para que desenvolvedores possam focar em lógica de negócio a nível de aplicação. Outros benefícios podem ser resumidos em:

  • Promove loose coupling;
  • Oferece ferramentas que facilitam a escrita de testes;
  • Diminui a quantidade de boilerplate code para singletons e factories;
  • Suporta configuração via XML e de forma programática via annotations.

Há outros fatores cruciais do framework, como o já citado Dependency Injection (e Inversion of Control). Com tais características, e com a premissa de abordar diferentes áreas de uma aplicação, é inevitável que o Spring torne-se algo complexo.

Logo, o framework é separado em seis "áreas fundamentais".

1: Core

Organograma do Spring Framework mostrando suas seis áreas
Spring Core e sua relação com os demais módulos (pluralsight.com)

O curso da Pluralsight, "Spring: The Big Picture", define o Spring Core como:

Spring Core is a dependency injection container.

Mais uma vez voltamos a citar Dependency Injection. E se esse pattern ainda soa exotérico para você, recomendo o ótimo "A quick intro to Dependency Injection: what it is, and when to use it", do freeCodeCamp.

Além disso, é o módulo que fornece funcionalidades como i18n, validações, data binding, conversores, etc. De maneira geral, é a "cola" e o fundamento de todo o framework.

2: Web

Diagrama com requisição e resposta através do Spring MVC
Fluxo de requisições e respostas através do Spring MVC (pluralsight.com)

O módulo Spring Web é responsável por lidar com requisições web. Isso pode ser feito através de dois frameworks:

  • Spring Web MVC: Que fornece ferramental para atender requisições e prover respostas através de Servlets;
  • Spring WebFlux: A forma de fazer aplicações web reativas (non-blocking) com Java e Spring.

O primeiro é a forma mais comum de fazer web, já o segundo envolve conceitos de requisições não-bloqueantes, que pretendo abordar melhor em posts vindouros.

3: AOP

AOP é acrônimo para o pomposo Aspect-Oriented Programming, que tem por finalidade aumentar a modularidade ao permitir a separação de cross-cutting concerns.

Ou, como muito bem define a Wikipedia:

Em Ciência da Computação, programação orientada a aspectos ou POA, é um paradigma de programação de computadores, criado por Gregor Kiczales e equipe na Xerox PARC (divisão de pesquisa da empresa Xerox), que permite aos desenvolvedores de software organizar o código fonte de acordo com a importância de uso na aplicação e separar em módulos (separation of concerns). Em contrapartida aos programas escritos no paradigma orientado a objetos, que possui código alheio a implementação do comportamento do objeto; todo código utilizado para implementar funcionalidades secundárias e que se encontra espalhado por toda a aplicação (crosscutting concern). A POA permite que esse código seja encapsulado e modularizado.

E se ainda está complicado de compreender, imagine a necessidade de aplicar a checagem de permissões por operações do usuário. É o tipo de responsabilidade que pode ficar espalhada pela aplicação. Com Spring AOP temos algo como abaixo:

@PreAuthorize("hasRole('admin')")
public void sensitiveOperation() {
    ...
}

Os detalhes da implementação de segurança não interessam ao sensitiveOperation, assim como o inverso.

4: Data

Com o Spring Data, interagir com dados fica muita mais simples. Abaixo, um exemplo de SELECT utilizando JDBC "na unha":

// Exemplo de database query com JDBC

try {
    Statement stmnt = conn.createStatement();

    try {
        ResultSet rs = stmnt.executeQuery(
            "SELECT COUNT(*) FROM foo");

        try {
            rs.next();
            int cnt = rs.getInt(1);
        } finally {
            rs.close();
        }
    } finally {
        stmnt.close();
    }
} catch (SQLException e) {
    // handle error
} finally {
    try {
        conn.close();
    } catch (SQLException e) {
        // handle error
    }
}

Agora o mesmo ensaio, só que com Spring Data:

int cnt = new JdbcTemplate(ds)
    .queryForInt("SELECT COUNT(*) FROM foo");

Nem preciso mencionar que gerenciar transações também fica muito mais simples:

@Transactional
public void operation() {
    // 1 ou mais queries
}

Para finalizar, controle de erros e inclusive ferramental para testes automatizados, são garantias fornecidas pelo Spring Data.

5: Integration

Imagem com a afirmação: Integração é sobre fazer diferentes sistemas e aplicações funcionarem juntos
Integração é sobre fazer diferentes sistemas e aplicações funcionarem juntos (pluralsight.com)

A intenção do Spring Integration é fazer com que sistemas se conversem. Não é só sobre expor suas soluções, mas também sobre consumir outros serviços.

Por exemplo, para criar um endpoint REST, anotações como RestController e GetMapping são ferramentas essenciais, fornecidas por esse módulo:

@RestController
public class AccountController {

    @GetMapping("/account/{id}")
    public Account find(@PathVariable int id) {
        ...
    }
}

Outro companheiro fiel é o RestTemplate, que você pode ler mais aqui.

6: Testing

O Dependency Injection é uma excelente ideia para garantir modularização e diminuir as amarras do acoplamento.

Com o Spring Testing, utilizar mocks, stubs e spies, como dependências injetáveis, fica muito mais fácil. Testar unitariamente (ou até mesmo de forma integrada) a sua aplicação é algo prático e factível.

O Spring Boot

Imagem com as dependências do spring-boot-starter-web
Árvore de dependências do Spring Boot (journaldev.com)

Ok. Finalmente! O que é o Spring Boot?

A documentação oficial define da seguinte forma:

Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can "just run".

We take an opinionated view of the Spring platform and third-party libraries so you can get started with minimum fuss. Most Spring Boot applications need minimal Spring configuration.

Imagine que para utilizar o Spring, cada módulo descrito acima é uma dependência que precisa ser instalada e configurada. E com isso, você vai ter uma porção de código boilerplate para executar o seu projeto.

Com Spring Boot, a biblioteca toma algumas decisões por você, configurando e declarando quais dependências seu projeto utilizará. Assim, com o mínimo de esforço você consegue ter a sua aplicação web funcionando em tempo recorde. Com alguns outros agrados, como métricas, health check, utilitários para deployment, etc.

Além do "auto-configuration", outro aspecto marcante do Spring Boot é que ele é standalone. Ou seja, toda aquela dança que tivemos com o Tomcat nos posts anteriores não é necessária aqui. O Spring Boot "embeda" o servidor web, e se encarrega disso para você.

É instalar e sair escrevendo código para o negócio, aos invés de escrever código para o framework.

Considerações finais

Esse post foi completamente baseado no curso Spring: The Big Picture, da plataforma de ensino Pluralsight. Se você quiser dar os seus primeiros passos com Java para web, utilizando Spring, esse curso é mais do que recomendado.

Spring Boot é sem dúvida a maneira mais indolor de começar a desenvolver para a web utilizando Java. Comece por ele, e vá customizando o conjunto de dependências e configurações sempre que necessário.

Escreva a sua primeira aplicação em Spring Boot agora.

Até a próxima.

Referências