Guia do Spring Framework: Spring Boot, Spring MVC, Spring REST, JPA, Hibernate, Spring Security, etc
Published: 2020-11-17 18:08:51

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/mzzj00bdipwv24sgrsm9.png)

__Introdução__

Estou aprendendo Spring há dois meses. Durante esse tempo, me deparei com uma série de siglas, nomes e conceitos totalmente novos. Eu tinha elaborado dois artigos com as anotações de um treinamento que fiz de Spring Boot, mas, desde então, tenho feito novos cursos relacionados ao Spring e pude aprender diversos outros assuntos relacionados a este universo, além de me aprofundar um pouco mais sobre os assuntos que tive contato no primeiro curso.

Como me organizo melhor escrevendo minhas ideias e anotações dos cursos, decidi criar um Guia do Spring para usar como ferramenta de consulta durante o meu aprendizado e compartilha-lo com toda a comunidade. Conforme for aprendendo novos assuntos e for me aprofundando nos temas que já citei, irei atualizando este artigo.


__Entendendo o universo Java e Spring__

__Spring__ é um framework Java que foi criado com o objetivo de facilitar o desenvolvimento de aplicações, utilizando os conceitos de Inversão de Controle e Injeção de Dependências. Dentro dele, há o __Spring MVC__ e o __Core Technologies__ (é a base do Spring, dentro dele há o pacote de injeção de dependências).

__Spring Boot__ é uma ferramenta que visa facilitar o processo de configuração e publicação de aplicações que usam o Spring, de maneira pé-configurada. Com esta ferramenta (presente no Spring Tools Service), você pode dizer ao Spring quantos módulos você quer usar (Spring MVC, Spring Data, Spring Cloud, Spring Security, Lombok, banco de dados, etc) e obterá uma configuração rápida para eles.

__Spring Tools (STS)__ é um plugin para as IDE (ambiente de desenvolvimento) do Eclipse, Visual Studio Code e Theia, que possibilita trabalhar com as funcionalidades do Spring de maneira mais fácil. Mas o STS não é pré-requisito para criação de projetos com Spring Boot, é possível usar qualquer outra ferramenta que suporta Java ou Maven. Para quem quiser criar o projeto de forma mais fácil, é possível utilizar também o site http://start.spring.io, que ajuda na criação de projetos com Spring Boot da mesma forma que o STS, de maneira intuitiva e fácil.

__Spring MVC__ é uma estrutura MVC completa orientada a HTTP (Web), gerenciada pela Spring Framework e baseada em Servlets. Os elementos mais populares nele são as classes anotadas @Controller, nas quais você implementa métodos que podem ser acessados usando diferentes solicitações HTTP. Tem um equivalente @RestController para implementar APIs baseadas em REST.

__API (Application Programming Interface)__ é um conjunto de rotinas, protocolos e ferramentas para construir aplicações que permite que dois sistemas se comuniquem entre si. Essencialmente, ela fornece a linguagem e o contrato para os dois sistemas interagirem entre si. Cada API tem documentação e especificação que determina como a informação pode ser transferida. Por exemplo, as possibilidades disponibilizadas pelo uso das APIs proporcionam para os desenvolvedores de softwares e aplicativos a possibilidade de conectar tecnologias heterogêneas, como diferentes bancos de dados. Utilizando o protocolo HTTP, nós temos o exemplo do __SOAP ou REST__, SOAP depende exclusivamente de XML para fornecer serviços de mensagens, enquanto REST oferece um método mais leve, usando URLs na maioria dos casos para receber ou enviar informações, utilizando os quatro verbos HTTP (GET, POST, PUT/PATCH e DELETE). Podemos utilizar as APIs com qualquer outra interface, como um CLI, utilizando o protocolo WebSocket ou, até mesmo, com uma biblioteca que facilita a extensão do seu código (como o caso da JPA).

__Constraints__ são regras que devem ser seguidas em conformidade com o REST.

__REST API__ é uma API que segue as regras especificadas pelas constraints.

__Spring REST__ é um termo que simboliza que temos uma REST API desenvolvida com o ecossistema Spring.

Quando uma API interage com outro sistema, o ponto de contato desta comunicação é chamado de __endpoint__, que pode incluir uma URL de um servidor ou serviço. O endpoint é o local de onde as APIs podem acessar os recursos que precisam para realizar suas funções.

__Spring Security__ é uma estrutura Java com foco em tornar a parte de autenticação e autorização algo mais simples de se fazer. Ele possui uma grande variedade de opções e é muito extensível. Com algumas poucas configurações, já podemos ter uma autenticação via banco de dados, LDAP ou até por memória. Além das integrações que ele suporta, há a possibilidade de criar suas próprias. Com o Security, também é possível protegermos as requisições web, através das permissões que atribuímos aos usuários autenticados.	

Um grande problema que os desenvolvedores passam é em fazer com que todo o time construa o software da mesma maneira, com as bibliotecas e configurações iguais. Para solucionar este problema, uma das maneiras mais comuns é se utilizar alguma ferramenta que compreenda alguma linguagem de script e copie as dependências e configurações para os lugares corretos, gerando um pacote com a aplicação. O __Maven__ é uma ferramenta desenvolvida pela Apache para gerenciar as dependências, controlar versão de artefatos, gerar relatórios de produtividade, manter o nível da qualidade do código e automatizar seus builds. Com o Maven, podemos isolar as bibliotecas utilizadas no projeto em um repositório compartilhado pela equipe (ou por toda a internet, como o caso do repositório central do Maven), evitando com que tenhamos que nos preocupar com duplicidade de dependências entre módulos do projeto e nem em disponibilidade das mesmas no repositório de código. Os arquivos de build do Maven usam arquivos XML para a sua configuração.

__Gradle__ é um sistema avançado de automatização de builds, que une o melhor da flexibilidade do __Ant__ com o gerenciamento de dependências e as convenções do Maven. Os seus arquivos de build são scripts escritos na linguagem Groovy. Ele possui um sistema de plugins, que adicionam novas funcionalidades ao seu core.

__Boilerplate code__ se refere a seções de códigos que devem ser incluídas em muitos lugares, com pouca ou nenhuma alteração. No Spring, utilizamos as anotações (annotations) para reduzir a quantidade de linhas de códigos desnecessárias.

__Lombok__ é uma biblioteca utilizada para gerar todos os getters, setters, constructors, equals and hashCode, toString, etc de uma determinada classe Model através de anotações, reduzindo consideravelmente a quantidade de código boilerplate. Para ativá-lo, é necessário colocar as dependências da biblioteca no arquivo de configuração __Pom.xml__. As anotações mais utilizadas são @Getter (gera os métodos get), @Setter (gera os métodos set), 
@EqualsAndHashCode, @ToString (gera o método toString), @NoArgsContructor (gera um construtor sem argumentos), @AllArgsConstructor (gera um construtor com argumentos), @Builder (cria os builders de forma mais fácil) e a anotação __@Data__ (substitui as anotações Getter, Setter, ToString, EqualsAndHashCode, NoArgsConstructor, AllArgsConstructor).

__Hibernate__ é um framework objeto relacional que simplifica a interação entre a aplicação e o banco de dados. Ele nasceu da necessidade de se facilitar a tarefa de criar uma aplicação Java que ajude a lidar com o banco de dados e de escrever muito SQL. Ele ajuda a representar tabelas de banco relacional através de classes e consegue gerar, em tempo de execução, o SQL necessário para interagir com o banco de dado. Além disso, ele possui um dialeto diferente para cada banco de dados (Oracle, PostgreSQL, Mongo, etc), permitindo que troquemos de banco de dados sem precisar alterar o código-fonte. A ideia do mapeamento objeto relacional do Hibernate funcionou tão bem que ele serviu de inspiração para a criação de uma especificação Java para persistência, que foi chamada de Java Persistence API (JPA).

__Java Persistance API (JPA)__ é uma especificação do Java EE para tratar o acesso e operações a base de dados que tem um Mapeamento Objeto Relacional (ORM). Ele evita a criação de SQL nativo misturado com código Java e permite a abstração da camada do banco de dados, evitando que se crie conexão manualmente, crie os updates e inserts manuais, etc. Ele também provê formas simples de realizar as operações na base de dados através da aplicação Java, além de permitir a migração para outros SGBD's, sem alterar quase nada.

__Mapeamento Objeto Relacional (ORM)__ é a representação de uma tabela de um banco de dados relacional através de classes Java. Enquanto temos tabelas, colunas e registros no banco de dados, nas linguagens orientada a objetos temos o equivalente com classe, atributos e objetos. Temos também as anotações que adicionarão metadados às classes e permitirão os frameworks ORMS, como o Hibernate, entrar em ação. Algumas das anotações que são muito utilizadas são: @Entity, @Table, @Id, @Column. Veja o exemplo da representação banco de dados e da linguagem orientada a objetos:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/7obchr4i1ha5t1bhru60.JPG)


__Spring Data__ tem por objetivo facilitar nosso trabalho com a persistência de dados de uma forma geral, agrupando diversos outros projetos relacionados a acesso aos dados. Dentro dele, há o __Spring Data JPA__, que permite implementar projetos JPA de forma simples, além de diversos outros projetos, como o Spring Data Commons, Spring Data MongoDB, Spring Data KeyValue, Spring Data REST, Spring Data Redis, Spring Data for Apache Cassandra, entre outros.

O __Spring Data JPA__ é um framework que nasceu para facilitar a criação dos nossos repositórios, liberando-nos da necessidade de implementar nossas interfaces referentes aos nossos repositórios ou __DAOs__, além de deixar pré-implementado algumas funcionalidades (como ordenação das consultas e de paginação de registros).

__Spring Session__ fornece uma API e implementações para gerenciar as informações da sessão de um usuário, ao mesmo tempo que torna trivial o suporte a sessões em cluster sem estar vinculado a uma solução específica de contêiner de aplicativo. Ele também fornece integração transparente com o HttpSession, WebSocket e WebSession.

__Spring REST Docs__ é utilizada para documentar APIs mais facilmente, é similar ao Swagger. Uma das vantagens de se utilizá-la, é de desenvolver APIs e incluir o teste de comportamento e a geração de documentação no mesmo processo.

__Spring HATEOAS__ é uma biblioteca de APIs que podemos usar para criar facilmente representações REST que seguem o princípio do HATEOAS (Hypertext as the Engine of Application State). De um modo geral, o princípio implica que a API deve guiar o cliente através da aplicação, retornando informações relevantes sobre as próximas etapas possíveis, junto com cada resposta.

__Spring Batch__ foi desenvolvido para a criação e implementação de jobs (máquina de estados com sequência de etapas que possuem uma lógica própria). Para entender a sua utilização, vamos supor que um banco precise processar diversas transações financeiras diariamente, esse processamento precisa ser rápido e confiável. Além disso, isso deve ser feito periodicamente e sem interrupções. Um job (tarefa) é uma aplicação que processa uma quantidade finita de dados sem interação ou interrupção.

__Spring Roo__ é uma ferramenta para o desenvolvimento rápido e fácil de aplicações Java, gerando parte do código fonte de uma aplicação com apenas algumas configurações e comandos iniciais feitos em linha de comando. Ele é capaz de gerar código de alguns dos principais frameworks Java, como o Spring, Hibernate, JSF e o GWT, utilizando o Maven. Além disso, a ferramenta também gera testes funcionais automatizados (com Selenium) e testes unitários (com JUnit).

__Spring Shell__ é uma ferramenta para criar um aplicativo de linha de comando (shell) completo para aplicativos Java. Com ele, podemos escrever nossos próprios comandos, como por exemplo, comandos para interagir com a API REST do seu projeto com conteúdo de arquivo local.

__Spring Web Services (Spring-WS)__ é um framework focado em facilitar a criação de serviços Web orientados a documentos, facilitando o desenvolvimento de serviços SOAP com contrato inicial (contract-first). O framework é capaz de gerar um WSDL baseando-se em um XSD e, então, mapear as mensagens para endpoints. Ele também oferece abstrações sobre APIs de parsing XML, suporte ao WS-Security e diferentes protocolos de transporte.

__Spring Web Flow__ é um framework que foi criado pelo Spring para facilitar o gerenciamento do fluxo de navegação em websites. Com o Web Flow, o fluxo de navegação é construído por meio da definição dos estados pelos quais o usuário passa e para chegar em cada um dos estados, o usuário dispara eventos. Por sua vez, entre os eventos que fazem as passagens de um estado para outro temos as transições de estado. Todo esse mecanismo citado é especificado em regras dentro de um arquivo XML, permitindo o seu reuso e diminuindo a escrita de código.

__Spring Webflux__ é um módulo que possibilita que aplicações web com Spring do lado servidor trabalhem de forma reativa. Quando o Spring MVC é utilizado para construir aplicações web, o processamento é feito de mono síncrono e bloqueante. Com o Spring Webflux, podemos construir aplicações que sejam assíncronas e não bloqueantes (trabalham com várias requisições simultaneamente). Ele é baseado no projeto Reactor, que é uma biblioteca de programação reativa sem bloqueio para a JVM. Tanto o Webflux quando o Reactor possuem dois tipos: Flux (consiste em um fluxo de 0 a n elementos) e Mono (consiste em um fluxo de 0 ou 1 elemento). 


__Swagger__ é um framework para descrição, consumo e visualização de serviços RESTful. Seu objetivo é permitir que a documentação possa evoluir no mesmo ritmo da implementação, já que pode ser gerada automaticamente com base em anotações do código.

__Microserviços__ são uma abordagem de arquitetura do desenvolvimento de software para a criação de aplicações, onde o software consiste em pequenos serviços independentes que se comunicam usando APIs bem definidas. A diferença entre a arquitetura de microserviços e as abordagens monolíticas tradicionais é como ela decompõe a aplicação por funções básicas. Cada uma das funções é chamada de serviço e pode ser criada e implementada de maneira independente, ou seja, cada serviço individual pode funcionar ou falhar sem comprometer os demais.

__Spring Cloud__ fornece ferramentas para os desenvolvedor criarem alguns dos padrões em sistemas distribuídos de forma mais clara (ex: gerenciamento de configuração, tokens únicos, bloqueios globais, eleição de liderança, estado do cluster, etc). A coordenação de sistemas distribuídos leva a padrões padronizados e, usando o Spring Cloud, os desenvolvedores podem criar rapidamente serviços e aplicativos que implementam esses padrões.

__Data Transfer Object (DTO)__ é um padrão de projetos utilizado para o transporte de dados entre diferentes componentes de um sistema, diferentes instâncias ou processos de um sistema distribuído ou diferentes sistemas via serialização. A ideia consiste em agrupar um conjunto de atributos numa classe simples de forma a otimizar a comunicação. Com o DTO, é possível retornar apenas os argumentos desejados de uma determinada entidade, deixando a aplicação maias segura.

__Apache Camel__ é um framework de integração de código-fonte aberto, que torna a integração de sistemas bastante simples. Essencialmente, ele é um roteador (routing engine), roteando os dados entre dois endpoints. O desenvolvedor define a origem dos dados, o destino, e a forma a qual ele será processado. O Camel não determina o tipo de dado que precisa ser transacionado, o que facilita a interação com vários sistemas, pois aproveita-se a mesma API, independentemente do protocolo ou tipo de dado de dado utilizado. 

__Tomcat__ é um servidor de internet desenvolvido pela Apache Software Foundation. Ele é, basicamente, um servidor HTTP. A diferença é que ele executa aplicações em Java, ao invés de site estáticos em HTML. Ele roda várias especificações diferentes do Java, como o Java EE, Java Servlet, JavaServer Pages e WebSocket.

Quanto uma aplicação for construída, há dois tipos de requisitos que devem ser implementados: requisitos funcionais da aplicação (regras de negócio) e requisitos não funcionais (parte da infraestrutura que vão controlar ações como transações, web services, conexões HTTP, etc). O __Java EE (Java Enterprise Edition)__ consiste em uma série de especificações bem detalhadas, dando uma receita de como deve ser implementado um software que faz cada um desses serviços de infraestrutura e, com isso, o desenvolvedor não precisa se preocupar em implementar os requisitos não funcionais. Mas, é necessário utilizar softwares que implementem as especificações Java EE para serem utilizadas em outras aplicações, que são chamadas de servidores de aplicação. Existem também, softwares que implementam apenas uma parte das especificações Java EE, que são chamados de __servlet container__. Um dos mais utilizados é o __Apache Tomcat__.

__Servlets__ são uma classe Java usada para estender as funcionalidades de um servidor, sendo uma das formas para se criar páginas dinâmicas utilizando o Java. Apesar de eles poderem responder a quaisquer tipos de requisições, normalmente são usados para estender as aplicações hospedadas por servidores web. O nome servlet vem da ideia de um pequeno servidor que tem objetivo de receber chamada HTTP, processá-las e devolver uma resposta ao cliente. Cada uma das servlet é responsável por uma página, sendo que ela lê os dados da requisição do cliente (request) e responde com dados do outro lado (response). A API Java Servlet proporciona ao desenvolvedor a possibilidade de adicionar conteúdo dinâmico em um servidor web, usando a plataforma Java.

__JavaServer Pages (JSP)__ é uma tecnologia onde podemos usar o HTML de forma direta, juntamente com a utilização do Java. Os servlets permitem que possamos escrever conteúdo dinâmico. Mas, se tivermos que cria-los toda hora para fazer este trabalho, teríamos muitos problemas em nossas páginas e na legibilidade do nosso código, já que sempre apareceria código Java misturado com HTML. Para resolver este problema, foi criada o JSP.

__Tomcat__ é um servidor de web Java desenvolvido pela Apache Software Foundation, é um servlet container. Ele implementa as tecnologias Java Servlet e JavaServer Pages (JSP), dentre algumas de menor relevância, e ele não é um container Enterprise JavaBeans (EJB). O Tomcat é distribuído como software livre e cobre parte da especificação Java EE com tecnologias como servlet e JSP, e tecnologias de apoio relacionadas como Realms e segurança, JNDI Resources e JDBC DataSources. Ele tem a capacidade de atuar também como servidor web ou pode funcionar integrado a um servidor web dedicado como o Apache ou o IIS (Internet Information Services - servidor web criado pela Microsoft para seus sistemas operacionais para servidores). Quando ele foi criado, foi endossado pela Sun Microsystem, oficialmente, como a implementação de referência para as tecnologias Java Servlet e JavaServerPages. Porém, atualmente, a implementação de referência é o GlassFish.

__JDBC DataSources__ é um conjunto de funcionalidades que padroniza e define como pode ser realizado o acesso ao banco de dados de forma transparente aos diversos fabricantes e tecnologias utilizadas para esse acesso.

__Sun GlassFish Enterprise Server__ é um servidor de aplicações rápido e fácil de usar, baseada na Plataforma Java e tecnologia Java EE para o desenvolvimento e entrega de aplicações e serviços web. É um servidor de aplicações de código aberto de nível corporativo que oferece produtividade, confiabilidade, desempenho, facilidade de uso e custando bem menos que os servidores de aplicações proprietárias.

__Enterprise JavaBeans (EJB)__ é um componente da plataforma Java EE que roda container de um servidor de aplicação e é usado para o desenvolvimento de aplicações distribuídas baseadas em componentes que são escaláveis, transacionais e seguros. Normalmente, ele contém a lógica de negócio que atua sobre os dados de negócio.

__Java Naming and Directory Interface (JDNI)__ é uma API que fornece funcionalidade de nomeação e diretório para aplicativos gravados utilizando o Java. Ele é independente de qualquer implementação de serviço de diretório específico e, assim, uma variedade de diretórios podem ser acessados de forma comum.

__Java Server Faces (JSF)__ é um framework onde é efetuada a elaboração de interfaces de usuários para sistema web, colocando componentes em um formulário e ligando-os a objetos Java, fazendo a separação entre a lógica e regras de negócio, a navegação e conexões com serviços externos, de acordo com o modelo MVC. Sua grande vantagem é a possibilidade de possuir um grande número de componentes e um design bastante flexível.

__Selenium__ é um conjunto de ferramentas de código aberto multiplataforma utilizado para testar aplicações web pelo browser de forma automatizada. Ele executa testes de funcionalidade da aplicação web e testes de compatibilidade entre browsers e plataformas diferentes.

__JUnit__ é um framework que facilita o desenvolvimento e execução de testes unitários em código Java. Ele fornece uma API completa para construir os testes e aplicações gráficas, além de um modo console para executar os testes criados. As vantagens de se utilizá-lo são: é orientado a objetos; facilita a criação, execução automática de testes e apresentação dos resultados; é grátis; pode verificar se cada unidade de código funciona da forma esperada.


__Thymeleaf__ é um mecanismo moderno, que serve para criar modelos Java em aplicações Web e independente do lado do servidor, sendo capaz de processar HTML, XML, Javascript, CSS e texto sem formatação. A ideia consiste em dinamizar páginas HTML e exibir o navegador, mas pode ser utilizado também com as páginas estáticas, segundo o conceito de Modelos Naturais para colocar a lógico nos modelos, sem usar o modelo como protótipo de design.


__Padrão MVC (Model-View-Controller)__

MVC é um padrão de arquitetura de software que separa sua aplicação em 3 camadas. A __camada de interação do usuário (View), a camada de manipulação dos dados (Model) e a camada de controle (Controller)__. O __View__ faz apenas a exibição dos dados (html/xml), o __Model__ é o responsável pela leitura e escrita de dados (além de suas validações). E o __Controller__ é o responsável por receber todas as requisições do usuário e, os seus métodos, chamados de actions, são responsáveis por uma página, controlando qual Model usar e qual View será mostrado ao usuário.
 
A sequência de criação das classes e pacotes do projeto são: __Model (Entity), Repository, Service, Controller.__

O __Model__ é onde fica os modelos da aplicação. O __Repository__ é onde fica a classe que fará transações com o banco de dados, ou seja, é um Design Pattern onde os dados são obtidos do banco de dados e é onde ocorre também a regra de negócio e este, retorna objetos de domínio que seriam as __Entidades__ (classes anotadas com @Entity). Ele é a subcamada responsável pela persistência de dados (recuperar, atualizar, inserir e apagar). O __Service__ é outro Design Pattern onde há somente a regra de negócio , ele não tem acesso direto ao banco de dados. É a subcamada __responsável pela regra de negócio__ (valida dados, executa regras de negócios, usa a Repository e a Entity para ter acesso ao banco de dados e persistir os dados). Já o __Controller__, é utilizado para lidar com a ligação da View com as outras partes do sistema, que são as regras de negócios e o banco de dados.

__DAO (Data Access Object)__ é um padrão para persistência de dados, onde seu principal objetivo é separar as regras de negócio de regras de acesso a banco de dados. Ou seja, é a subcamada responsável pela regra de negócio. Ele é muito utilizado com a arquitetura MVC, onde toda separação de conexões, SQLs e funções diretas ao banco são tratadas no DAO.


__COMEÇANDO UM PROJETO COM SPRING INITALIZR__

Para criar um projeto do zero Spring, é possível fazer isso de diversas maneiras possíveis, como utilizando o Spring Tools Service ou o site Spring Initalzr. Como essa segunda forma é mais fácil e intuitiva, vamos utilizá-la para criar o nosso projeto. Para começar, acesse o site https://start.spring.io/. Em Novembro de 2020, a interface do sistema estava assim:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/7qf6x59v96o0jij3nhhy.png)
 
Em Project, você pode escolher entre criar o projeto com Maven ou Gradle. Em Language, você seleciona a linguagem do seu projeto. Em Spring Boot, você escolhe a versão do Spring, a que vem marcada como padrão é sempre a última versão estável dele. Em Project Metadata, temos as configurações do projeto, como o grupo, nome, descrição, pacote (Jar ou War) e versão da linguagem escolhida. Em Dependencies, vamos adicionar todas as dependências iniciais que utilizaremos em nosso projeto Spring, no decorrer do projeto, é possível adicionar novas dependências no arquivo Pom.xml. Por fim, em Generate, vamos gerar o nosso projeto inicial em formato ZIP. Algumas dependências disponíveis no Spring e que são muito utilizadas são:

•	DataJPA: Para utilizar o Spring Data e outros recursos da JPA e Hibernate.
•	Web: Para criar um web service.
•	DevTools: Ajuda com questões de restart e live reloading.
•	Rest Repositories: Para utilizar o Spring Data Rest em nossos CRUD’s.
•	HSQLDB: Para utilizar esse banco de dados em memória.
•	Security: permite utilizar as funcionalidade do Spring Security
•	Oracle Driver: adiciona os drivers para se utilizar o banco de dados Oracle.
•	Data MongoDB: adiciona as dependências do banco MongoDB;
•	Lombok: permite utilizar as anotações do Lombok.

Selecionei algumas opções e configurações do projeto, conforme mostrado na imagem a seguir: 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/9w8dulrbctojsarwagqj.png)
	
Clique em Generate e será baixado o seu projeto em formato ZIP. Descompacte ele na pasta do seu projeto e abre o STS (Spring Tools Service). Dentro do STS, clique em File - > Import... - > Existing Maven Projects - > em Root Directory selecione o caminho do seu projeto - > clique em Finish. Agora, o STS vai baixar todas as dependências necessárias para o projeto funcionar. No arquivo application.properties, é necessário adicionar as configurações do banco de dados (utilizei o banco de dados Oracle) e adicionar as dependências do Oracle no arquivo pom.xml. O arquivo application.properties vai ficar mais ou menos assim:

spring.datasource.url= jdbc:oracle:thin:@localhost:1521:xe
spring.datasource.username=System
spring.datasource.password= suasenha
spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver
spring.batch.job.enabled=false
spring.jpa.hibernate.ddl-auto = update
spring.jpa.show-sql=true

O campo username e senha são os dados de acesso do banco, em ddl-auto se colocar como “update” o banco será atualizado após cada salvamento de arquivo, se colocar como “create-drop” o banco inteiro será apagado e criado após cada modificação no código e com o “create”, o banco é criado uma vez só. A url é a referência de onde está o banco (pode estar em um site externo).

__Pom.xml (Project Object Model)__ é um arquivo que contém configurações do projeto usados pelo Maven para fazer buid (construir o projeto). Neste arquivo, são adicionadas as dependências de outras bibliotecas que utilizamos no projeto.

Agora, para rodar nosso projeto, basta clicar com o botão direito em cima da pasta do projeto (em Project Explorer) -> Run As... -> Spring Boot App. Com isso, nossa configuração inicial de um projeto Spring terminou. Para ver o resultado, basta abrir o seu navegador e acessar a URL http://localhost:8080 e ver a mensagem de “Ok” que aparece na página!


__JPA (Java Persistance API)__

Fiz uma pequena apresentação do JPA no início deste artigo, agora irei falar mais um pouco sobre ele. O arquivo __Persistence.xml__ possui todos os arquivos com todas as configurações de acesso de dados (do JPA) e é, através deste arquivo, que o JPA cria o __EntityManagerFactory__, que é uma fábrica de gerenciamento de entidades (por exemplo, se temos duas bases de dados diferentes, teremos um EntityManagerFactory para cada uma delas). Com o objeto EntityManagerFactory, é possível adquirir diversas __EntityManager__, ou seja, toda vez que for necessário fazer uma operação, é feito uma requisição de instância de EntityManager e ele é o objeto que vai fazer as operações (persistir, alterar, deletar e consultar) na base de dados. Para fazer as requisições, o JPA utiliza a interface __JPA Repository__, que contém as operações básicas das entidades e o EntityManager é quem irá fazer essas operações. A classe Repository é declarada como uma Interface que estende o __JpaRepository<User, Long>__ e é ele quem vai realizar todas as operações referentes a uma única entidade. Neste exemplo, ele está referenciando a entidade User com atributo de identificação id do tipo Long. O primeiro parâmetro (User) é a classe que vamos querer que se comunique com o banco de dados. O segundo parâmetro (Long), é a classe Wrapper do ID da classe/tabela, que o banco está fazendo a referência.

O __JpaRepository__ possui alguns métodos próprios para realizar as operações de CRUD e buscas por parâmetros com as nossas classes do Model e que são muito utilizados no dia a dia. Alguns destes métodos são:
o	findAll() - retorna uma lista com todos os elementos da classe;
o	findAllById() – busca um elemento através do seu id e o retorna;
o	save – salva um elemento na tabela (cria um novo elemento);
o	saveAll() – salva todos os elementos na tabela (para casos de array ou objetos compostos);
o	get() – pegar os elementos para realizar operações, podendo ser combinado com o byId ou o All;

No __Service__, são criados todos os métodos que farão as operações de CRUD no banco de dados (busca todos, busca por id, salvar dados, atualizar dados, excluir, busca avançada, etc).

O __Controller__ é quem faz o meio de campo entre o back-end e o banco de dados. É nele onde fica todos os métodos com os verbos HTTP de comunicação e é ele quem chamará os métodos de operações que estão nas classes Service.


__Containers, Injeção de Dependência e Inversão de Controle__

O __Spring container__ é o núcleo do Framework Spring. O container irá cria os objetos, conectá-los, configurá-los e gerencia o seu ciclo de vida completo, da sua criação até a destruição. O container usa __injeção de dependência (DI)__ para gerenciar os componentes que compõe uma aplicação e estes objetos são chamados de __Spring Beans__. O container obtém suas instruções sobre quais objetos instanciar, configurar e montar lendo os metadados de configuração fornecidos, que são representados por XML, anotação Java ou código Java. O Spring vem com diversas implementações de contêineres, que podem ser categorizados em dois tipos diferentes: 

•	Bean factories: são tipos simples de container, fornecendo suporte básico para a injeção de dependência); 
•	ApplicationContext: baseiam-se na noção de bean factories, mas adiciona algumas funcionalidades extraa em comparação com sua classe pai. O Spring vem com diferentes sabores de ApplicationContext, as mais utilizadas são:
o	AnnotationConfigApplicationContext: Carrega um contexto de aplicação Spring de uma ou mais classes de configuração baseadas em Java;
o	ClassPathXmlApplicationContext: Carrega uma definição de contexto de um ou mais arquivos XML localizados no classpath;
o	FileSystemXmlApplicationContext: Carrega uma definição de contexto de um ou mais arquivos XML localizados no sistema de arquivos;
o	AnnotationConfigWebApplicationContext: Carrega um contexto de aplicação Web Spring de uma ou mais classes de configuração baseadas em Java.

__Bean__ é uma classe onde o programador declara que o Spring container é quem vai gerenciar as instâncias desta classe, é o Spring quem vai criar gerenciar e destruir todas as instâncias dela. Quando uma classe é marcada com a anotação @Component, @Service, @Resository ou @Controller, o Spring vai saber que essa classe é um Bean e, com isso, essas classes agora podem sofrer pontos de injeção (injeção de dependência). 

__Inversão de controle__ é um princípio de engenharia de software pelo qual o controle de objetos ou partes de um programa é transferido para um container ou estrutura e é usado, frequentemente, no contexto da programação orientada a objetos. Em contraste com a programação tradicional, onde nosso código faz chamadas para uma biblioteca, a inversão de controle permite que uma estrutura assuma o controle do fluxo de um programa e faça chamadas para nosso código. Algumas vantagens desta arquitetura são: maior facilidade em testar um programa, isolando um componente ou simulando suas dependências e permitindo que os componentes se comuniquem por meio de contratos; dissociar a execução de uma tarefa de sua implementação; maior modularidade de um programa; entre outros. A inversão de controle pode ser alcançada por meio de vários mecanismos, como por exemplo: padrão de design de estratégia, padrão de localizador de serviço, padrão factory e injeção de dependência.

__Injeção de dependências (DI – Dependency Injection)__ é um tipo de inversão de controle __(IoC – Inversion of Control)__ que dá o nome ao processo de prover instâncias de classes que um objeto precisa para funcionar. Para ativar a injeção de dependência, basta colocar a anotação __@Autowired__ em uma propriedade, método ou construtor. Utilizando o DI em uma propriedade, a classe ficaria assim:

public class ClienteServico {
  @Autowired
  private ClienteRepositorio repositorio;
  //continuação...
}


__Guia das Anotações (Annotations) Java e Spring__

As anotações foram introduzidas no Java 5 e são utilizadas para anotar métodos, campos e classes, de forma que essas marcações possam ser tratadas pelo compilador, ferramentas de desenvolvimento e bibliotecas. Uma anotação muito utilizada no Java é o __@Override__, que sobrescreve métodos. As anotações são colocadas em cima do atributo/classe/métodos que se deseja referenciar e as mais utilizadas no Spring são:

•	@Enumerated = diz que o atributo/método é uma enumeração. A propriedade (value = EnumType.STRING) diz que vamos gravar este ENUM como texto e a propriedade (value = EnumType.ORDINAL) diz que vamos guardá-la como número;
•	@SpringBootAplication = habilita diversos recursos, como a configuração do Spring baseado em Java, verificação de componentes e configuração automática do Spring Boot.
•	@Builder = cria automaticamente o código necessário para instanciar uma classe. Exemplo: Person builder().name(“Adam Savage”).city(“San Fransciso”).build();
•	@NotBlank = indica que este campo não poderá ser nulo (campo obrigatório);
•	@Lob = permite receber textos grandes e sempre converte a sua variável para bytes no banco de dados (seja para um texto longo ou simplesmente uma sequência de bytes, como no caso de salvar uma imagem);
•	@JsonFormat = é utilizada para formatação de data, através da propriedade (shape=JsonFormat.Shape.STRING, pattern="dd-MM-yyyy");
•	@Autowired = faz a injeção de dependência;
•	@Component = é um dos estereótipos que define para o Spring que a classe será um bean gerenciado por ele. Existe outros estereótipos que são mais recomendados de se utilizar, devido a sua especificidade, como @Service (indica que a classe é um service), @Controller (indica que a classe é um controller), @Repository (indica que a classe é um repository). A @Component é a mais genérica dessas anotações;
•	@PostConstructor = é utilizada em métodos que precisam ser executados após a sua classe ser instanciada.

__ANOTAÇÕES DE CRUD__
•	@RequestMapping = determina qual método HTTP será utilizado e qual será sua URL. Por exemplo, em @RequestMapping(value = "/posts", method = RequestMethod.GET) nós temos a URL “/posts” e o método HTTP será o GET (vai buscar informações do banco de dados e retorna-las). Algumas anotações possuem parâmetros para manipular um dado por vez (como o byId) ou todos ao mesmo tempo (como o All). A partir do Spring Framework 4.3, surgiram novas anotações que expressam de forma mais clara o que cada método está fazendo:
o	@GetMapping utiliza o verbo GET, buscando informações do banco de dados;
o	@PostMapping utiliza o verbo POST, para inserir novos dados no banco de dados;
o	@PatchMapping utiliza o verbo PATCH, fazendo alterações em campos do banco de dados;
o	@PutMapping utiliza o verbo PUT, fazendo alterações em campos do banco de dados;
o	@DeleteMapping utiliza o verbo DELETE, excluindo dados do banco de dados.
•	@PathVariable = é utilizado quando o valor da variável é passada diretamente na URL como parte dela, e não como um parâmetro passado após o sinal de interrogação (?);
•	@RequestParam = é utilizado quando temos vários parâmetros passados por uma URL (como nome e e-mail);
•	@RequestBody = é usada para requisitar um corpo de argumentos em métodos HTTP;
•	@Value = indica um valor padrão inicial para um campo (permite configurar uma label);
 
__ANOTAÇÕES DO LOMBOK__
•	@Data = gera, automaticamente, os getters, settters, toString, equalsAndHashCode (mas não cria o construtor) de uma classe. Também é possível colocar o @Getter e o @Setter em cada um dos atributos (caso não queira gera-los com o @Data);
•	@AllArgsConstructor = cria um construtor com todos os atributos; 
•	@NoArgsConstructor = cria um construtor sem atributos;
•	@Getter = gera todos os getters da classe caso seja colocada acima da classe e gera o getter de um atributo, caso seja adiciona acima de um atributo;
•	@Setter = gera todos os setters da classe caso seja colocada acima da classe e gera o setters de um atributo, caso seja adiciona acima de um atributo;
•	@ToString = gera o método toString da classe;
•	@EqualsAndHashCode = gera todos os equalsAndHashCode da classe. Usando o parâmetro (exclude= {“firstName”, “lastName”}), é possível ignorar alguns dos campos na geração dos equals/hashCode;
•	@Builder = cria objetos sem a necessidade de construtores e métodos setter, (caso os objetos sejam imutáveis);

__ANOTAÇÕES DE BANCO DE DADOS/JPA__
•	@Entity = simboliza que uma classe é uma entidade (ela é uma tabela no banco de dados). É a nossa classe principal, onde ficará os atributos dos objetos, construtores, getters e setters. Como é uma tabela, podemos declarar o nome dela usando @Table(name = ”TB_EXEMPLO”);
•	@Id = declara um atributo como sendo id único da classe;
•	@GeneratedValue(strategy = GenerationType.AUTO) = gera um id automaticamente, e embaixo dessa anotação é colocado @SequenceGenerator (name = "useraluno_sequence", sequenceName = "user_seq_id", allocationSize = 1) para criar a sequência dos id de forma automática. Isso é válido caso você esteja utilizando o banco de dados Oracle (que possui tecnologia sequence), caso esteja utilizando o MySQL, você terá que definir o valor inicial direto no banco de dados.
•	@OneToMany(mappedBy = “categoria_id”) = informa que o registro de uma entidade está relacionado com vários registros de outra entidade. O parâmetro é usado no lado fraco do relacionamento e faz com que o relacionamento seja bidirecional;
•	@ManyToOne = informa um tipo de relacionamento muitos para um (vários registros de uma entidade estão relacionados com um registro de outra entidade);
•	@JoinColumn = indica que a classe/atributo na qual você está utilizando é a dona ou o lado forte do relacionamento. Essa anotação adiciona uma chave estrangeira do lado forte;
•	@JoinTable = é utilizado para criar uma referência entre duas tabelas. Por exemplo, vamos supor que nós temos as tabelas de Aluno e Faculdade, e que cada faculdade terá vários alunos, mas o aluno vai estudar em apenas uma faculdade. Nesse caso, vamos precisar de uma terceira tabela para fazer o mapeamento dos alunos para a faculdade. Esta tabela intermediária (vamos chamar de Faculdade_Aluno) vai possuir duas chaves estrangeiras (uma de Aluno e outra de Faculdade) para ligar as três tabelas. Para fazermos o mapeamento desta situação, utilizamos a anotação @JoinTable no Spring. Segue um exemplo:
@JoinTable(name="faculdade_aluno",
                  joinColumns = {@JoinColumn(name = "faculdade_id",
                  referencedColumnName = "id")},
                  inverseJoinColumns = {@JoinColumn(name = "aluno_id",
                  referencedColumnName =  id")})


__Requisições HTTP (CRUD)__

__ResponseEntity__ é uma função que traduz o retorno de uma requisição, representando toda a resposta HTTP (código de status, cabeçalhos e corpo). Podemos usá-lo para configurar totalmente a resposta HTTP.
 
Passamos o responseEntity como retorno do método. No retorno, chamamos o ResponseEntity e o método ok(), que representa o status HTTP 200 ok. 
 
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/r9rmkuydpu4bspsorqf1.png)

Neste método do Controller, que retorna uma busca por id, passamos um optional para buscar o carro. Caso ele encontre o carro pelo id, irá retornar o status 200 OK e os dados do carro, caso contrário, irá retornar o status 404 NOT FOUND.
  
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/xylbpnxa2l7hg2av1qs9.png)
 
__@ResponseStatus(HttpStatus.CREATED)__ é uma anotação que retorna um status HTTP toda vez que um método for chamado. O CREATED retorna o status 201 Created, indicando que um novo objeto foi criado com sucesso.

Nas classes SERVICE, vamos criar os métodos de busca e inserção que vamos utilizar em nosso exemplo. Como exemplo, vou utilizar a classe AlunoService: 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/72bakfi3la72knts6rk1.png)
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/0h5ka1vvw2b9i6mkjmsf.png)

Nas classes CONTROLLER, vamos utilizar os métodos de busca (que criamos nos SERVICE) para se comunicar com o banco de dados. Como exemplo, vou utilizar a classe AlunoController:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/q914agokl9pv1lv2irgt.png)
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/vb8zdsmzjubn4f3t9qkq.png)

OFF-TOPIC: Vou mostrar um exemplo de como seria esta busca pelo navegador. Vamos ter a URL completa que chama nosso método (http://localhost:8081/produtos/paginador) e passaremos dois parâmetros em nossa busca. Em “pagina=1” estamos dizendo para exibir a página 1 e em “linhas=1” para exibir a busca a partir da primeira linha. A busca pela URL ficará assim: http://localhost:8081/produtos/paginador?pagina=1&linhas=1


__Outros aprendizados com Spring__

Caso você crie um atributo que contenha data usando o LocalDate, é necessário adicionar em a anotação @Convert(converter = Jsr310JpaConverters.LocalDateConverter.class), para fazer o mapeamento da data de maneira correta.


__ComamandLineRunner e populando dados direto no banco__

O Spring fornece duas interfaces (__CommandLineRunner e ApplicationRunner__) para rodar partes específicas de códigos quando a aplicação for totalmente inicializada. Estas interfaces são chamadas um pouco antes do run(), uma vez que a SpringApplication é concluída. Vou utilizar um exemplo para popularmos (inserir) dados no banco de dados sempre que a aplicação iniciar. Explicação do código:

Linhas 3 a 8: injeção de dependência em produtoRepository, categoriaRepository e imagemRepository 
Linhas 10 a 12: método principal, que está rodando toda a aplicação do Spring.
Linhas 14 e 15: início do método que está implementando a interface CommandLineRunner.
Linha 16 a 24: Cadastro de um novo item na tabela de Categorias, instanciando um objeto chamado cat1. A classe irá chamar o builder() e chamará os métodos com os campos que serão preenchidos. O Produto e Imagem são duas outras tabelas do nosso banco e a imagem recebeu apenas uma URL como parâmetro.			
Linhas 25 a 28: aqui vamos unir o que criamos das tabelas produtos e imagem, e, depois, salvá-las em suas próprias tabelas (JOIN entre as tabelas).

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/2s2qudwz7wnjygnvcnwy.png)


__Manipulando Tabelas__

No exemplo a seguir, referenciei a ligação das tabelas utilizando as chaves primárias e estrangeiras das mesmas. O fetch=FetchType.EAGER irá carregar todos os produtos que estão relacionado a uma determinada categoria (chamado de Eager Loading, do Hibernate).

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/tbbx9avz18zmdtpg8b5d.png)

O @JsonIgnore é usado no nível de campos, para marcar uma propriedade (ou lista de propriedades) que serão ignoradas (não serão exibidas), conforme o exemplo:
 
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/5we6f9u1utekkeym6gfq.png)

Passando a anotação @Query, nós podemos criar uma busca de dados personalizada. Colocando como parâmetro o nativeQuery como true, é possível passar comandos de busca em SQL puro. O nome do método de busca que estamos criando é o procuraPorNome, como pode ser visto no seguinte exemplo: 
  
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/olj7jjfrezd9pwlsu19h.png)


__REFERENCIAS__

https://www.dclick.com.br/2010/09/15/o-que-e-o-maven-e-seus-primeiros-passos-com-a-ferramenta/
https://www.adrianolisboa.com/afinal-de-contas-o-que-e-o-gradle-e-como-usa-lo/
https://blog.algaworks.com/tutorial-jpa/
https://www.tutorialspoint.com/spring/spring_bean_definition.htm
https://medium.com/lifeinhurry/what-is-spring-container-spring-core-9f6755966fe9
https://blog.algaworks.com/injecao-de-dependencias-com-spring/
https://www.baeldung.com/inversion-control-and-dependency-injection-in-spring
https://dicasdejava.com.br/spring-boot-como-criar-a-estrutura-de-uma-aplicacao-web-do-zero-com-spring-initializr/
https://blog.matheuscastiglioni.com.br/criando-meu-primeiro-web-service-com-spring-boot/