Pular para o conteúdo principal

Capítulo 2: Estrutura de um Projeto Spring Boot

Introdução​

Um projeto Spring Boot segue uma estrutura padronizada baseada nas convenções do Maven. Essa organização facilita a navegação no código e permite que os desenvolvedores encontrem rapidamente os arquivos necessários.

Objetivos do Capítulo​

Ao final deste capítulo, você será capaz de:

  • Entender a organização dos diretórios de um projeto Spring Boot
  • Identificar o papel de cada arquivo importante
  • Organizar seu código de acordo com as boas práticas
  • Navegar de forma eficiente em um projeto Spring Boot

Visão Geral da Estrutura​

Estrutura Completa​

greeting-app/
├── .mvn/ # Maven Wrapper
│ └── wrapper/
│ ├── maven-wrapper.jar
│ └── maven-wrapper.properties
├── src/
│ ├── main/
│ │ ├── java/ # Código-fonte Java
│ │ │ └── com/example/greeting/
│ │ │ └── GreetingApplication.java
│ │ └── resources/ # Recursos da aplicação
│ │ ├── static/ # Arquivos estáticos (CSS, JS, imagens)
│ │ ├── templates/ # Templates (Thymeleaf, Freemarker)
│ │ ├── application.properties # Configuração principal
│ │ └── application.yml # Configuração YAML (alternativa)
│ └── test/
│ ├── java/ # Testes unitários e de integração
│ │ └── com/example/greeting/
│ │ └── GreetingApplicationTests.java
│ └── resources/ # Recursos de teste
│ └── application-test.properties
├── target/ # Arquivos compilados (gerado)
├── .gitignore # Arquivos ignorados pelo Git
├── mvnw # Maven wrapper (Unix/macOS)
├── mvnw.cmd # Maven wrapper (Windows)
├── pom.xml # Configuração Maven
├── HELP.md # Documentação gerada
└── README.md # Documentação do projeto

Diretório Raiz​

1. Arquivo pom.xml​

Papel: Arquivo de configuração do Maven (Project Object Model)

Conteúdo principal:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<!-- Parent Spring Boot -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.0</version>
<relativePath/>
</parent>

<!-- Identificadores do projeto -->
<groupId>com.example</groupId>
<artifactId>greeting</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>greeting</name>
<description>Application de salutation</description>

<!-- Propriedades -->
<properties>
<java.version>17</java.version>
</properties>

<!-- Dependências -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<!-- Plugin de build -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

Seções importantes:

SeçãoDescrição
<parent>Herda a configuração do Spring Boot
<groupId>, <artifactId>, <version>Coordenadas Maven do projeto
<properties>Configuração global (versão Java, encoding, etc.)
<dependencies>Lista de dependências do projeto
<build>Configuração do processo de build

2. Maven Wrapper (mvnw, mvnw.cmd)​

Papel: Permite executar o Maven sem instalá-lo globalmente

Vantagens:

  • Garante a versão do Maven para todos os desenvolvedores
  • Não é necessário instalar o Maven manualmente
  • Scripts incluídos no projeto

Uso:

Linux/macOS:

./mvnw clean install
./mvnw spring-boot:run

Windows:

mvnw.cmd clean install
mvnw.cmd spring-boot:run

3. Arquivo .gitignore​

Papel: Lista de arquivos que não devem ser versionados com o Git

Conteúdo típico:

# Arquivos compilados
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/

# IDE
.idea/
*.iml
.vscode/
.classpath
.project
.settings/

# Sistema
.DS_Store
Thumbs.db

# Logs
*.log

# Arquivos temporários
*.tmp
*.bak

Diretório src/main/java​

Estrutura dos Pacotes​

Convenção: Organizar o código em camadas funcionais

src/main/java/com/example/greeting/
├── GreetingApplication.java # Classe principal
├── controller/ # Controllers REST/MVC
│ ├── GreetingController.java
│ └── UserController.java
├── service/ # Lógica de negócio
│ ├── GreetingService.java
│ └── UserService.java
├── repository/ # Acesso a dados
│ ├── UserRepository.java
│ └── ProductRepository.java
├── model/ # Entidades e DTOs
│ ├── entity/
│ │ ├── User.java
│ │ └── Product.java
│ └── dto/
│ ├── UserDTO.java
│ └── ProductDTO.java
├── config/ # Configuração Spring
│ ├── SecurityConfig.java
│ └── DatabaseConfig.java
├── exception/ # Tratamento de erros
│ ├── ResourceNotFoundException.java
│ └── GlobalExceptionHandler.java
└── util/ # Classes utilitárias
└── DateUtil.java

Arquitetura em Camadas​

Responsabilidades de cada camada:

CamadaPapelAnotações
ControllerGerencia as requisições HTTP@RestController, @Controller
ServiceLógica de negócio@Service
RepositoryAcesso a dados@Repository, interface JPA
ModelRepresentação dos dados@Entity, POJO

Classe Principal: GreetingApplication.java​

Conteúdo:

package com.example.greeting;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class GreetingApplication {

public static void main(String[] args) {
SpringApplication.run(GreetingApplication.class, args);
}
}

Anotação @SpringBootApplication:

Esta anotação é um atalho que combina três anotações:

@SpringBootApplication
=
@SpringBootConfiguration // Configuração Spring
+ @EnableAutoConfiguration // Auto-configuração
+ @ComponentScan // Scan de componentes

Papel de cada anotação:


Diretório src/main/resources​

Visão Geral​

src/main/resources/
├── static/ # Arquivos estáticos
│ ├── css/
│ │ └── style.css
│ ├── js/
│ │ └── script.js
│ └── images/
│ └── logo.png
├── templates/ # Templates (Thymeleaf)
│ ├── index.html
│ └── user.html
├── application.properties # Configuração principal
├── application-dev.properties # Configuração desenvolvimento
├── application-prod.properties # Configuração produção
├── application.yml # Configuração YAML (alternativa)
├── banner.txt # Banner personalizado na inicialização
└── data.sql # Script SQL de inicialização

1. Diretório static/​

Papel: Contém arquivos estáticos servidos diretamente

Tipos de arquivos:

  • CSS (folhas de estilo)
  • JavaScript (scripts client-side)
  • Imagens (PNG, JPG, SVG)
  • Fonts (fontes personalizadas)

Acesso:

http://localhost:8080/css/style.css
http://localhost:8080/js/script.js
http://localhost:8080/images/logo.png

Estrutura recomendada:

static/
├── css/
├── js/
├── images/
├── fonts/
└── favicon.ico

2. Diretório templates/​

Papel: Contém os templates de views (caso utilize um template engine)

Motores de template suportados:

  • Thymeleaf (recomendado)
  • Freemarker
  • Mustache
  • Groovy Templates

Exemplo Thymeleaf:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Greeting</title>
</head>
<body>
<h1 th:text="${message}">Default message</h1>
</body>
</html>

3. Arquivo application.properties​

Papel: Configuração principal da aplicação

Formato: chave=valor

Exemplos de configurações:

# Porta do servidor
server.port=8080

# Nome da aplicação
spring.application.name=greeting-app

# Configuração do banco de dados
spring.datasource.url=jdbc:postgresql://localhost:5432/mydb
spring.datasource.username=postgres
spring.datasource.password=secret

# JPA/Hibernate
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true

# Logs
logging.level.root=INFO
logging.level.com.example=DEBUG

# Formato de datas
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=America/Montreal

4. Arquivo application.yml (Alternativa)​

Papel: Mesmo que application.properties, mas em formato YAML

Formato: Hierárquico com indentação

Exemplo equivalente:

server:
port: 8080

spring:
application:
name: greeting-app

datasource:
url: jdbc:postgresql://localhost:5432/mydb
username: postgres
password: secret

jpa:
hibernate:
ddl-auto: update
show-sql: true

logging:
level:
root: INFO
com.example: DEBUG

Comparação:

FormatoVantagensDesvantagens
propertiesSimples, familiarRepetitivo para estruturas complexas
ymlLegível, hierárquicoSensível à indentação

5. Profiles de Configuração​

Conceito: Configurações diferentes conforme o ambiente

Arquivos de profiles:

application.properties           # Configuração padrão
application-dev.properties # Desenvolvimento
application-test.properties # Testes
application-prod.properties # Produção

Ativação de um profile:

Via application.properties:

spring.profiles.active=dev

Via linha de comando:

java -jar app.jar --spring.profiles.active=prod

Via variável de ambiente:

export SPRING_PROFILES_ACTIVE=prod

Exemplo de configuração por ambiente:

application-dev.properties:

server.port=8080
spring.datasource.url=jdbc:h2:mem:testdb
logging.level.root=DEBUG

application-prod.properties:

server.port=80
spring.datasource.url=jdbc:postgresql://prod-server:5432/mydb
logging.level.root=WARN

Diretório src/test/java​

Estrutura dos Testes​

src/test/java/com/example/greeting/
├── GreetingApplicationTests.java # Teste de inicialização
├── controller/
│ └── GreetingControllerTest.java # Testes do controller
├── service/
│ └── GreetingServiceTest.java # Testes do service
└── repository/
└── UserRepositoryTest.java # Testes do repository

Teste de Inicialização Padrão​

package com.example.greeting;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class GreetingApplicationTests {

@Test
void contextLoads() {
// Verifica se o contexto Spring carrega corretamente
}
}

Papel: Verificar se a aplicação inicia sem erros


Diretório target/​

Papel: Contém os arquivos compilados e o JAR final

Gerado por: Maven durante o build

Conteúdo:

target/
├── classes/ # Classes compiladas (.class)
├── test-classes/ # Testes compilados
├── generated-sources/ # Fontes geradas
├── maven-status/ # Status do Maven
└── greeting-0.0.1-SNAPSHOT.jar # JAR executável final

Importante: Este diretório é ignorado pelo Git (no .gitignore)

Limpeza:

mvn clean

Organização por Funcionalidade vs por Camada​

Abordagem 1: Por Camada (Recomendada para projetos pequenos)​

com.example.greeting/
├── controller/
│ ├── UserController.java
│ └── ProductController.java
├── service/
│ ├── UserService.java
│ └── ProductService.java
├── repository/
│ ├── UserRepository.java
│ └── ProductRepository.java
└── model/
├── User.java
└── Product.java

Vantagens:

  • Simples e clara
  • Fácil de entender para iniciantes
  • Padrão do Spring Boot

Desvantagens:

  • Difícil de escalar para projetos grandes
  • Acoplamento entre funcionalidades

Abordagem 2: Por Funcionalidade (Recomendada para projetos grandes)​

com.example.greeting/
├── user/
│ ├── UserController.java
│ ├── UserService.java
│ ├── UserRepository.java
│ └── User.java
├── product/
│ ├── ProductController.java
│ ├── ProductService.java
│ ├── ProductRepository.java
│ └── Product.java
└── order/
├── OrderController.java
├── OrderService.java
├── OrderRepository.java
└── Order.java

Vantagens:

  • Alta coesão
  • Baixo acoplamento
  • Facilita a migração para arquitetura de microservices

Desvantagens:

  • Menos padrão
  • Pode ser confuso no início

Convenções de Nomenclatura​

Pacotes​

Convenção: Tudo em minúsculas, palavras separadas por pontos

com.example.greeting           // ✅ Correto
com.example.greeting.service // ✅ Correto
com.Example.Greeting // ❌ Errado (maiúsculas)
com.example.greeting_service // ❌ Errado (underscore)

Classes​

Convenção: PascalCase (primeira letra de cada palavra em maiúscula)

UserController        // ✅ Correto
GreetingService // ✅ Correto
userController // ❌ Errado (começa com minúscula)
user_controller // ❌ Errado (underscore)

Sufixos recomendados:

TipoSufixoExemplo
ControllerControllerUserController
ServiceServiceUserService
RepositoryRepositoryUserRepository
EntityNenhumUser, Product
DTODTOUserDTO, CreateUserDTO
ExceptionExceptionResourceNotFoundException
ConfiguraçãoConfigSecurityConfig

Métodos​

Convenção: camelCase (primeira letra minúscula)

getUserById()         // ✅ Correto
findAllUsers() // ✅ Correto
GetUserById() // ❌ Errado (começa com maiúscula)
get_user_by_id() // ❌ Errado (underscore)

Variáveis e Atributos​

Convenção: camelCase

String userName;      // ✅ Correto
int userId; // ✅ Correto
String UserName; // ❌ Errado (começa com maiúscula)
String user_name; // ❌ Errado (underscore)

Constantes​

Convenção: SCREAMING_SNAKE_CASE (tudo em maiúsculas, underscores)

public static final int MAX_USERS = 100;              // ✅ Correto
public static final String API_BASE_URL = "/api/v1"; // ✅ Correto
public static final int maxUsers = 100; // ❌ Errado (camelCase)

Exercícios Práticos​

Exercício 1: Explorar a Estrutura​

Objetivo: Familiarizar-se com a estrutura de um projeto

Instruções:

  1. Crie um projeto com o Spring Initializr (apenas Spring Web)
  2. Importe-o no VS Code
  3. Identifique:
    • O arquivo pom.xml
    • A classe principal
    • O arquivo application.properties
    • O diretório de testes
  4. Desenhe a estrutura em papel

Exercício 2: Criar uma Estrutura de Pacotes​

Objetivo: Organizar o código em camadas

Instruções:

  1. No projeto anterior, crie a estrutura:
    com.example.demo/
    ├── controller/
    ├── service/
    ├── repository/
    └── model/
  2. Crie classes vazias em cada pacote
  3. Verifique a compilação

Exercício 3: Configurar Profiles​

Objetivo: Criar configurações por ambiente

Instruções:

  1. Crie application-dev.properties:
    server.port=8080
    logging.level.root=DEBUG
  2. Crie application-prod.properties:
    server.port=80
    logging.level.root=WARN
  3. Teste a ativação de cada profile

Perguntas de Revisão​

  1. Qual arquivo contém as dependências do Maven?

  2. Para que serve o diretório target/?

  3. Qual a diferença entre static/ e templates/?

  4. O que contém a anotação @SpringBootApplication?

  5. Como nomear um arquivo de configuração para o ambiente de desenvolvimento?

  6. Qual é a convenção de nomenclatura para classes controller?

  7. Onde você coloca os arquivos CSS e JavaScript?

  8. Qual a diferença entre application.properties e application.yml?


Resumo do Capítulo​

Pontos-Chave​

  • A estrutura do Spring Boot segue as convenções do Maven
  • O código-fonte está em src/main/java
  • Os recursos estão em src/main/resources
  • Organização em camadas: Controller → Service → Repository
  • Os testes ficam em src/test/java
  • Os arquivos de configuração utilizam profiles

Boas Práticas​

  • Respeitar as convenções de nomenclatura Java
  • Organizar o código em pacotes lógicos
  • Separar as configurações por ambiente
  • Utilizar sufixos descritivos para as classes
  • Comentar códigos complexos
  • Manter uma estrutura clara e coerente

Próximos Passos​

No próximo capítulo, vamos aprofundar em:

Capítulo 3: Configuração com application.properties

  • Propriedades disponíveis do Spring Boot
  • Configuração de banco de dados
  • Configuração de logs
  • Propriedades customizadas

Voltar ao Módulo 2