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.
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.
Chegaremos no Spring Boot, mas antes, vamos por partes, como diria aquele famoso serial killer.
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:
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".
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.
O módulo Spring Web é responsável por lidar com requisições web. Isso pode ser feito através de dois frameworks:
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.
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.
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.
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.
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.
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.
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.