Camada que atua sob framework Spring, simplificando-o e modernizando-o, seguindo padrão MVC. Spring implementa padrão IoC (Inversion of Control), onde os objetos (Spring Beans / Beans) são instanciados automaticamente pelo container do Spring, dispensando criação manual.
JDK (Java Development Kit) é kit de ferramentas e bibliotecas para desenvolver aplicações Java. Gradle é automatizador de build moderno que usa linguagem baseada em Groovy ou Kotlin para configurar projetos.
Em 'start.spring.io', selecione:
Estrutura tradicional/standard (Structure/Package by Layer), onde cada camada (Controller, Service, Repository) é organizada em pacotes separados. Melhor cenário: sistemas mais simples, bem estruturados, com responsabilidades claras (como em CRUDs). Pior cenário: pouca flexibilidade para mudanças, acoplamento entre camadas e dificuldade em evoluir o domínio:
com.company.project
├── ProjectApplication.java
├── config
│ ├── SecurityConfig.java
│ ├── DatabaseConfig.java
│ └── SwaggerConfig.java
├── controller
│ ├── UserController.java
│ └── ProductController.java
├── service
│ ├── UserService.java
│ ├── UserServiceImpl.java
│ ├── ProductService.java
│ └── ProductServiceImpl.java
├── repository
│ ├── UserRepository.java
│ └── ProductRepository.java
├── model
│ ├── entity
│ │ ├── User.java
│ │ └── Product.java
│ └── dto
│ ├── UserDTO.java
│ ├── CreateUserRequest.java
│ └── ProductDTO.java
├── exception
│ ├── GlobalExceptionHandler.java
│ ├── ResourceNotFoundException.java
│ └── ValidationException.java
├── mapper
│ ├── UserMapper.java
│ └── ProductMapper.java
├── security
│ ├── JwtTokenProvider.java
│ └── CustomUserDetailsService.java
└── util
├── DateUtil.java
└── ValidationUtil.java
src/main/resources:
resources
├── application.yml
├── application-dev.yml
├── application-prod.yml
├── static
│ └── (static files)
├── templates
│ └── (template files)
└── db
└── migration
├── V1__Create_users_table.sql
└── V2__Add_products_table.sql
src/test:
src/test/java/com/company/project
├── controller
│ └── UserControllerTest.java
├── service
│ └── UserServiceTest.java
└── repository
└── UserRepositoryTest.java
Estrutura moderna (Structure/Package by Feature), onde cada feature/recurso é organizada em pacotes separados, sendo ideal para projetos complexos, escaláveis e microservices. Melhor cenário: sistemas grandes, com várias funcionalidades, onde cada módulo agrupa lógica, testes e regras relacionadas. Pior cenário: pode gerar duplicação de código se não for bem estruturado, e o time precisa se organizar para manter o alinhamento entre features:
com.myapp.project
├── Application.java
├── user/
│ ├── UserController.java
│ ├── UserService.java
│ ├── UserRepository.java
│ ├── User.java (entity)
│ ├── UserDto.java
├── product/
│ ├── ProductController.java
│ ├── ProductService.java
│ ├── ProductRepository.java
│ ├── Product.java
│ ├── ProductDto.java
├── auth/
│ ├── AuthController.java
│ ├── AuthService.java
│ ├── JwtService.java
│ ├── JwtAuthenticationFilter.java
│ ├── CustomUserDetailsService.java
│ ├── LoginRequest.java
│ ├── RegisterRequest.java
│ ├── AuthResponse.java
│ └── JwtUtil.java
├── config/
│ ├── AppConfig.java
│ ├── SecurityConfig.java
│ ├── DatabaseConfig.java
│ ├── SwaggerConfig.java
│ └── JwtConfig.java
├── exception/
│ ├── GlobalExceptionHandler.java
│ ├── ResourceNotFoundException.java
│ ├── ValidationException.java
│ ├── UnauthorizedException.java
│ ├── InvalidTokenException.java
│ └── TokenExpiredException.java
├── mapper/
│ ├── UserMapper.java
│ └── ProductMapper.java
└── util/
├── DateUtil.java
├── ValidationUtil.java
└── PasswordUtil.java
src/main/resources:
resources
├── application.yml
├── application-dev.yml
├── application-prod.yml
├── static
│ └── (static files, css, js, images)
├── templates
│ └── (template files, html, thymeleaf)
├── config
│ ├── security.yml
│ ├── swagger.yml
│ ├── e.g. application.yml
│ ├── logging.yml
│ └── database.ym
└── db
└── migration
├── V1__Create_users_table.sql
└── V2__Add_products_table.sql
src/test:
src/test/java/com/myapp/project
├── user/
│ ├── UserControllerTest.java
│ ├── UserServiceTest.java
│ └── UserRepositoryTest.java
├── product/
│ ├── ProductControllerTest.java
│ ├── ProductServiceTest.java
│ └── ProductRepositoryTest.java
└── config/
└── SecurityConfigTest.java
Arquitetura moderna (Hexagonal Architecture / Ports and Adapters), onde a aplicação é organizada em camadas concêntricas, com o domínio central isolado de detalhes de infraestrutura, sendo ideal para projetos complexos, escaláveis e microservices. Melhor cenário: sistemas complexos, com alto desacoplamento, onde o domínio é protegido de detalhes externos, permitindo fácil troca de tecnologia e alta testabilidade. Pior cenário: curva de aprendizado mais alta, abstrações adicionais, exigindo mais esforço para implementar no início:
src/main/java/com/myapp/project
├── application/
│ ├── port/
│ │ ├── input/
│ │ │ ├── UserUseCase.java
│ │ │ └── ProductUseCase.java
│ │ └── output/
│ │ ├── UserPersistencePort.java
│ │ └── ProductPersistencePort.java
│ ├── service/
│ │ ├── UserServiceImpl.java
│ │ └── ProductServiceImpl.java
│ ├── dto/
│ │ ├── UserDto.java
│ │ └── ProductDto.java
│ └── mapper/
│ ├── UserMapper.java
│ └── ProductMapper.java
├── domain/
│ ├── model/
│ │ ├── User.java
│ │ └── Product.java
│ ├── exception/
│ │ ├── ResourceNotFoundException.java
│ │ ├── ValidationException.java
│ │ ├── UnauthorizedException.java
│ │ ├── InvalidTokenException.java
│ │ └── TokenExpiredException.java
│ └── vo/
│ └── (Value Objects opcionais)
├── infrastructure/
│ ├── input/
│ │ ├── rest/
│ │ │ ├── UserController.java
│ │ │ └── ProductController.java
│ │ └── config/
│ │ ├── SwaggerConfig.java
│ │ └── SecurityConfig.java
│ └── output/
│ ├── persistence/
│ │ ├── UserRepositoryImpl.java
│ │ └── ProductRepositoryImpl.java
│ ├── security/
│ │ ├── JwtTokenProvider.java
│ │ └── CustomUserDetailsService.java
│ └── config/
│ └── DatabaseConfig.java
├── shared/
│ └── exception/
│ └── GlobalExceptionHandler.java
└── Application.java
Elaborado por Mateus Schwede
ubsocial.github.io