Escrito por Eduardo Rost,

5 minutos de leitura

Guia Prático: usando Gradle para criar uma estrutura para seu projeto

Descubra insights valiosos para otimizar seus projetos de forma coesa e eficiente, a partir da utilização do Gradle.

Compartilhe este post:

A nossa arquitetura é fundamentada em microsserviços, predominantemente em Java, e atende a múltiplos clientes que compartilham a mesma infraestrutura, porém com bancos de dados distintos. Por isso, classificamos nossa arquitetura como multilocação.

Para evitar duplicação de código para conexão de banco de dados nos serviços, padronização de logs, configuração de cache, segurança, toda lógica de customização necessária para funcionalidade do produto, entre outras funcionalidades comuns que foram necessárias ao longo dos anos. Então, decidimos criar bibliotecas para cada necessidade, a ideia era que essas bibliotecas fossem independentes e utilizadas conforme a necessidade dos serviços.

Entretanto, à medida que o projeto crescia, o número de bibliotecas aumentava e a tarefa de gerenciar o versionamento de cada uma delas para mantê-las atualizadas tornou-se desafiadora. Além disso, algumas bibliotecas tornaram-se dependentes umas das outras. Para proporcionar um contexto visual mais claro, consulte o diagrama de exemplo

Imagine que você precise fazer alterações na biblioteca do locatário, incluindo atualizar o log, o custom e o cache lib. Para lidar com isso, estamos utilizando o framework Spring. Um aspecto crucial é manter a mesma versão do Spring em todos os projetos.

Por isso, optamos por desenvolver nossa própria estrutura. Essencialmente, consolidamos todas as bibliotecas em um único projeto e utilizamos o Gradle para gerenciá-las de forma integrada

E como fizemos isso?

Cache de exemplo | registro de exemplo | exemplo de inquilino

Bibliotecas existentes no projeto o build.gradle dentro de cada subprojeto é muito simples, apenas a descrição do projeto e das dependências. Como você pode ver no exemplo-cache

description = Dependências de "Cache de exemplo"

 { 
    api( "org.springframework.boot:spring-boot-starter-data-redis" ) 

    api(project( ':example-tenant' )) 
    api(project( ':example-logging' )) 
}

framework-bom

A lista de materiais (BOM) do Compose permite gerenciar todas as versões da biblioteca do Compose especificando apenas a versão da BOM. A própria BOM possui links para as versões estáveis ​​das diferentes bibliotecas do Compose, de forma que funcionem bem juntas. Ao usar a BOM no seu aplicativo, você não precisa adicionar nenhuma versão às próprias dependências da biblioteca do Compose. Quando você atualiza a versão da BOM, todas as bibliotecas que você está usando são atualizadas automaticamente para suas novas versões. [1]

Então, para um melhor gerenciamento de versões criamos um projeto BOM

description = "Exemplo (lista de materiais)"

 apply plugin: 'java-platform'
 apply plugin: "maven-publish"
 apply from: " $rootDir /gradle/publications.gradle"

 group = "com.example"

 dependências { 
restrições { 
  parent.subprojects.sort { " $it .name" }.each { 
   api it 
  } 
} 
} 

publicação { 
publicações { 
  mavenJava (MavenPublication) { 
   artefatoId = 'framework-bom'
    de componentes.javaPlatform 
  } 
} 
}

plataforma-framework

[2] O plugin Java Platform traz a capacidade de declarar plataformas para o ecossistema Java. Uma plataforma pode ser usada para diferentes fins:

uma descrição dos módulos que são publicados juntos (e, por exemplo, compartilham a mesma versão)

um conjunto de versões recomendadas para bibliotecas heterogêneas. Um exemplo típico inclui o Spring Boot BOM

compartilhando um conjunto de versões de dependência entre subprojetos

Neste subprojeto, definimos o BOM do framework Spring e podemos definir restrições para importação de bibliotecas de terceiros.

plug-ins { 
    id  'java-platform'
 } 

javaPlatform { 
    allowDependencies() 
} 

dependências { 
    api(platform( "org.springframework:spring-framework-bom: $springFrameworkVersion " )) 

    restrições { 
        api( 'org.yaml:snakeyaml:2.0' ) { 
            porque 'Algum exemplo de restrição'
         } 
    } 
}

dependencyManagement.gradle

Usamos o plugin de gerenciamento de dependências do Spring, então aqui definimos quais componentes e versão usaremos.

aplicar plugin: "io.spring.dependency-management"

 dependencyManagement { 
    dependencies { 
        dependency "org.springframework.boot:spring-boot: $springBootVersion "
         dependência "org.springframework.boot:spring-boot-starter-security: $springBootVersion "
         dependência "org.springframework.boot:spring-boot-starter-web: $springBootVersion "
         dependência "org.springframework.boot:spring-boot-starter-data-redis: $springBootVersion "

         dependência "org.springframework.boot:spring- teste de inicialização: $springBootVersion "
     } 
}

incrementVersion.gradle

Tarefas para obter versão e incrementar versão do projeto. Usamos essas tarefas em nosso pipeline.

tarefa printVersion { 
    doLast { 
        println "versão= ${versão} "
     } 
} 

tarefa incrementVersion { 
    doLast { 
  def versionParts = version.split(/\./).collect{it.toInteger()} 
  def bumpedMajor = versionParts[0] 
  def bumpedMinor = versionParts[1] 
  def bumpedPath = versionParts[2] 

  if (project.hasProperty( 'bumpPatch' )) { 
   bumpedPath += 1 
  } else { 
   bumpedMinor += 1 
  } 

  def bumpedVersion = " ${bumpedMajor} . ${bumpedMinor} . ${bumpedPath} "
         String s = buildFile.getText().replaceFirst( "version=' $version '" , "version=' $bumpedVersion '" ) 
        buildFile.setText(s) 
    } 
}

módulo.gradle

Configure o jar e as tarefas de publicação.

aplicar plugin: 'java-library'

 jar { 
manifesto.attributes[ "Título de implementação" ] = project.name 
manifest.attributes[ "Versão de implementação" ] = project.version 
manifest.attributes[ "Criado por" ] = " ${System.getProperty("java.version")} ( ${System.getProperty("java.specification.vendor")} )"
 } 

tarefas fontesJar( tipo : Jar, dependeOn: classes) { 
duplicatesStrategy = DuplicatesStrategy.EXCLUDE 
archiveClassifier . set ( "fontes" ) 
de sourceSets.main.allSource 
} 

publicação { 
publicações { 
  mavenJava (MavenPublication) { 
   de componentes.java 
   artefato fontesJar 
  } 
} 
}

configurações.gradle

Incluir todos os subprojetos no projeto raiz

pluginManagement { 
    repositories { 
        gradlePluginPortal() 
    } 
} 

include "example-cache"
 include "example-tenant"
 include "example-logging"
 include "framework-platform"
 include "framework-bom"

 rootProject.name = "example"
 rootProject.children. cada {projeto -> 
    project.buildFileName = " ${project.name} .gradle"
 }

construir.gradle

É o coração da estrutura. Aqui configuramos tudo o que é necessário para que o framework funcione corretamente.

buildscript { 
repositórios { 
  maven { 
   url "https://plugins.gradle.org/m2/"
   } 
} 
dependências { 
  classpath "org.jfrog.buildinfo:build-info-extractor-gradle:4.15.2"
   classpath "io.spring .gradle:dependency-management-plugin:1.1.0"
 } 
} 

ext { 
moduleProjects = subprojects.findAll { it.name.startsWith( "example-" ) } 
javaProjects = subprojects - project( ":framework-bom" ) - projeto ( ":framework-platform" ) 
} 

configure(allprojects) { projeto -> 
repositórios { 
  mavenLocal() 
  mavenCentral() 
  jcenter() 
} 
} 

configure([rootProject] + javaProjects) { projeto -> 
grupo = "com.example"

 aplicar plugin: "java-library"
 apply plugin: "maven-publish"
 apply from: " $rootDir /gradle/dependencyManagement.gradle"

 sourceCompatibility = 17 
targetCompatibility = 17 

configurações { 
  dependencyManagement { 
   canBeConsumed = false
    canBeResolved = false
    visível = false
   } 
  correspondente { it.name.endsWith( "Classpath" ) }.all { it.extendsFrom(dependencyManagement) } 
} 

dependências { 
  dependencyManagement(enforcedPlatform(dependencies.project(path: ":framework-platform" ))) 

  compileOnly( "org.projectlombok: lombok: $lombokVersion " ) 
  annotationProcessor( "org.projectlombok:lombok: $lombokVersion " ) 
} 

 test { 
  useJUnitPlatform() 
} 
} 

configure(moduleProjects) { projeto -> 
aplicar de: " ${rootDir} /gradle/module.gradle"
 } 

configure(rootProject) { 
description = "Estrutura de exemplo"
 } 

allprojects { 
version= '1.1.0'
 } 

aplicam-se a partir de: " $rootDir /gradle/incrementVersion.gradle"

Assim, com este código de estrutura você poderá construir seu próprio framework para seu projeto. Você pode verificar todo o trabalho em meu repositório .

E como usar o framework em um projeto?

Para usar o framework em projetos é bem simples, é necessário apenas importar o BOM e as bibliotecas desejadas no build.gradle, conforme código abaixo.

dependencyManagement { 
    importações { 
        mavenBom "com.example:framework-bom:1.1.0"
     } 
} 


dependências { 
  implementação 'com.example:example-tenant'
   implementação 'com.example:example-cache'
 }
Compartilhe este post: