Monorepositório com Java: organização de código na prática

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Monorepositório com Java: organização de código na prática

\n

No desenvolvimento Java moderno, a questão da escolha entre um monorepositório (monorepo) e vários repositórios separados surge cada vez mais. Monorepositório é uma abordagem onde todo o código do projeto (vários serviços, bibliotecas, configurações) é armazenado em um único repositório Git. Neste artigo, vamos analisar como organizar um monorepositório com Java na prática: desde a estrutura de pastas até a configuração de build e CI/CD. Você obterá exemplos de código prontos e recomendações que ajudarão a evitar erros típicos.

\n\n

Por que um monorepositório para Java?

\n

O monorepositório é especialmente útil para projetos Java onde muitos módulos dependem uns dos outros. Principais vantagens:

\n
    \n
  • Versão única de dependências — todos os módulos usam a mesma versão das bibliotecas, eliminando conflitos.
  • \n
  • Refatoração simplificada — a alteração de uma API em um módulo é imediatamente visível em todos os dependentes.
  • \n
  • Configuração de build compartilhada — Gradle ou Maven são configurados uma vez para todos os módulos.
  • \n
  • Integridade do CI/CD — um único pipeline para todos os serviços, facilitando o rastreamento de alterações.
  • \n
\n

No entanto, o monorepositório exige disciplina: sem uma estrutura clara, ele se transforma em caos. Vamos considerar a organização correta.

\n\n

Estrutura do monorepositório para um projeto Java

\n

Estrutura recomendada para um monorepositório com Java (exemplo com Gradle):

\n
my-monorepo/\n├── build.gradle.kts          # arquivo de build raiz\n├── settings.gradle.kts       # inclui todos os módulos\n├── gradle.properties         # propriedades comuns\n├── libs/                     # bibliotecas comuns\n│   ├── common-utils/\n│   │   ├── build.gradle.kts\n│   │   └── src/\n│   └── logging/\n│       ├── build.gradle.kts\n│       └── src/\n├── services/                 # microsserviços\n│   ├── user-service/\n│   │   ├── build.gradle.kts\n│   │   └── src/\n│   └── payment-service/\n│       ├── build.gradle.kts\n│       └── src/\n├── config/                   # configurações (ex.: checkstyle, spotbugs)\n│   └── checkstyle.xml\n└── docker/                   # Dockerfile para cada serviço\n    ├── user-service.Dockerfile\n    └── payment-service.Dockerfile\n
\n

Princípios-chave:

\n
    \n
  • Os módulos são divididos em libs (bibliotecas) e services (aplicações executáveis).
  • \n
  • O build.gradle.kts raiz define os plugins e versões comuns.
  • \n
  • O arquivo settings.gradle.kts inclui todos os subprojetos.
  • \n
\n

Exemplo de settings.gradle.kts:

\n
rootProject.name = "my-monorepo"\n\ninclude(\n    "libs:common-utils",\n    "libs:logging",\n    "services:user-service",\n    "services:payment-service"\n)\n
\n\n

Configuração de dependências entre módulos

\n

A principal tarefa de um monorepositório é gerenciar dependências internas. Vamos considerar um exemplo onde user-service depende de common-utils.

\n

Passo 1. No gradle.properties raiz, declaramos as versões:

\n
# gradle.properties\nkotlinVersion=1.9.0\nspringBootVersion=3.2.0\ncommonUtilsVersion=1.0.0\n
\n

Passo 2. No build.gradle.kts raiz, conectamos os plugins e definimos as configurações comuns:

\n
plugins {\n    id("java-library") apply false\n    id("org.springframework.boot") version "3.2.0" apply false\n    id("io.spring.dependency-management") version "1.1.4" apply false\n}\n\nallprojects {\n    group = "com.example"\n    version = "1.0.0"\n\n    repositories {\n        mavenCentral()\n    }\n}\n\nsubprojects {\n    apply(plugin = "java-library")\n\n    java {\n        sourceCompatibility = JavaVersion.VERSION_17\n        targetCompatibility = JavaVersion.VERSION_17\n    }\n\n    dependencies {\n        implementation("org.slf4j:slf4j-api:2.0.9")\n        testImplementation("org.j                

Blogs

Book Recommendations