DEV Community

Renato Cardoso Alves
Renato Cardoso Alves

Posted on • Edited on

Guia detalhado sobre Java Modules

Com a chegada do Java 9, a plataforma Java ganhou um novo sistema de módulos, que foi uma das maiores mudanças desde a introdução das Generics no Java 5. O sistema de módulos, também conhecido como Projeto Jigsaw, permite dividir a aplicação em módulos distintos com dependências explícitas. Isso melhora a organização, segurança e manutenibilidade do código.

Introdução aos módulos

Um módulo em Java é uma unidade de agregação de pacotes. Ele encapsula pacotes e recursos e especifica quais deles são acessíveis a outros módulos e quais não são. O sistema de módulos tem como objetivo principal oferecer maior controle sobre a visibilidade de classes e pacotes e ajudar a construir aplicações mais robustas e seguras.

Definindo um módulo

Para definir um módulo, você precisa criar um arquivo module-info.java na raiz do diretório do módulo. Esse arquivo contém as declarações que definem o nome do módulo e as suas dependências.

Exemplo de um module-info.java básico:

module com.example.myapp {
    requires java.sql;
    exports com.example.myapp.api;
}
Enter fullscreen mode Exit fullscreen mode

Neste exemplo:

  • 'module com.example.myapp' define o nome do módulo
  • 'requires java.sql' declara que este módulo depende do módulo 'java.sql'.
  • exports com.example.myapp.api permite que outros módulos acessem os pacotes dentro módulo 'com.example.myapp.api'

Estrutura do projeto com módulo

Suponha que temos dois módulos 'com.example.myapp' e 'com.example.util'.

A estrutura do projeto seria algo assim:

my-modular-project/
├── com.example.myapp/
│   ├── module-info.java
│   └── com/example/myapp/
│       ├── Main.java
│       └── api/
│           └── MyService.java
└── com.example.util/
    ├── module-info.java
    └── com/example/util/
        └── Utility.java

Enter fullscreen mode Exit fullscreen mode

Exemplo de implementação

Vamos implementar um exemplo simples onde um módulo com.example.myapp utiliza um serviço fornecido pelo módulo com.example.util.

com.example.util/module-info.java

module com.example.util {
    exports com.example.util;
}
Enter fullscreen mode Exit fullscreen mode

com.example.util/com/example/util/Utility.java

package com.example.util;
public class Utility {
    public static String getGreeting() {
        return "Hello from Utility!";
    }
}
Enter fullscreen mode Exit fullscreen mode

com.example.myapp/module-info.java

module com.example.myapp {
    requires com.example.util;
}
Enter fullscreen mode Exit fullscreen mode

com.example.myapp/com/example/myapp/Main.java

package com.example.myapp;

import com.example.util.Utility;

public class Main {
    public static void main(String[] args) {
        System.out.println(Utility.getGreeting());
    }
}
Enter fullscreen mode Exit fullscreen mode

Compilação e execução dos módulos

Para compilar e executar módulos, você pode usar o comando 'javac' e 'java' com a opção '--module-path' para especificar onde os módulos estão localizados.
Compilação

javac -d out --module-source-path src $(find src -name "*.java")
Enter fullscreen mode Exit fullscreen mode

Execução

java --module-path out -m com.example.myapp/com.example.myapp.Main
Enter fullscreen mode Exit fullscreen mode

Recursos adicionais

Diretrizes de acesso

Você pode usar a diretiva 'opens' para permitir acesso reflexivo a pacotes, por exemplo, para bibliotecas e frameworks como Spring e Hibernate:

module com.example.myapp {
    requires com.example.util;
    opens com.example.myapp.internal to some.framework;
}
Enter fullscreen mode Exit fullscreen mode

Serviços e provedores

Java Modules também suportam um mecanismo de serviços para facilitar a implementação de padrões de design como Inversão de Controle (IoC).

Definição de serviço:

module com.example.util {
    exports com.example.util;
    provides com.example.util.MyService with com.example.util.MyServiceImpl;
}
Enter fullscreen mode Exit fullscreen mode

Uso do serviço:

module com.example.myapp {
    requires com.example.util;
    uses com.example.util.MyService;
}
Enter fullscreen mode Exit fullscreen mode

No código do cliente, você pode obter um instância do serviço usando o 'ServiceLoader':

ServiceLoader<MyService> serviceLoader = ServiceLoader.load(MyService.class);
MyService service = serviceLoader.findFirst().orElseThrow();
Enter fullscreen mode Exit fullscreen mode

Conclusão

O sistema de módulos em Java oferece uma maneira poderosa e flexível de organizar o código, controlar dependências e melhorar a segurança das aplicações. Ele é especialmente útil para grandes projetos que podem se beneficiar de uma estrutura modularizada. Ao entender e aplicar os conceitos de módulos, você pode construir aplicações Java mais robustas e manuteníveis.

Top comments (0)