Atualizado: 04/10/2025

Este conteúdo é original e não foi gerado por inteligência artificial.

Criação de Objetos Dinâmicos com Proxy em Java

Em Java, Proxy é um mecanismo que permite criar objetos que se comportam como instâncias de interfaces, mas cujas chamadas de métodos podem ser interceptadas e processadas de forma personalizada. A funcionalidade é fornecida pela classe java.lang.reflect.Proxy.

Proxies não são comuns no desenvolvimento do dia a dia. Eles são usados, em geral, em cenários de infraestrutura, como sistemas de plugins, roteamento de chamadas para servidores remotos, ligação entre eventos e ações ou depuração de chamadas de métodos.

Um proxy criado em tempo de execução implementa um ou mais interfaces, redirecionando as chamadas de seus métodos para um handler.


Proxy e InvocationHandler

Um proxy de interface em Java não define o comportamento dos métodos em tempo de execução. Em vez disso, a lógica é delegada a um objeto que implementa a interface InvocationHandler.

Essa interface possui um único método:

Object invoke(Object proxy, Method method, Object[] args) throws Throwable

Parâmetros do método:

  • proxy: o próprio objeto proxy em que o método foi chamado.
  • method: o objeto Method que representa o método da interface chamado.
  • args: array de argumentos passados para o método ou null se não houver argumentos. Argumentos de tipos primitivos são convertidos para seus wrappers (por exemplo, int em Integer, boolean em Boolean).

O valor retornado pelo método invoke() será o valor devolvido ao chamador do método do proxy.

Sempre que um método do proxy é chamado, o método invoke() do handler é executado, recebendo o Method correspondente e os argumentos da chamada.


Exemplo: Criando um Handler para Depuração

O exemplo a seguir mostra um handler que registra no console as chamadas dos métodos e depois as repassa para o objeto real:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

class DebugHandler implements InvocationHandler {

    private Object target;

    DebugHandler(Object target) {
        this.target = target;
    }

    public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {

        // Exibe o nome do objeto alvo
        System.out.print(target);
        // Exibe o nome do método
        System.out.print("." + m.getName() + "(");
        // Exibe os argumentos
        if (args != null) {
            for (int i = 0; i < args.length; i++) {
                if (i != args.length - 1) System.out.print(", ");
                System.out.print(args[i]);
            }
        }
        System.out.println(")");

        // Executa o método no objeto alvo
        return m.invoke(target, args);
    }
}

Criando um Proxy

A criação de um proxy é feita com o método estático Proxy.newProxyInstance():

static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)

Parâmetros:

  • loader: o carregador de classes a ser usado. Geralmente utiliza-se o carregador do sistema, obtido com ClassLoader.getSystemClassLoader().
  • interfaces: array de interfaces que o proxy implementará.
  • h: instância de InvocationHandler que processará as chamadas aos métodos.

Exemplo Completo

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

class Program {

    public static void main(String[] args) {

        Object start = new Point(10, 15);
        var handler = new DebugHandler(start);

        Movable proxy = (Movable) Proxy.newProxyInstance(
                ClassLoader.getSystemClassLoader(),
                new Class[] { Movable.class },
                handler
        );

        proxy.move(25);
        proxy.move(15);
        proxy.move(10);
    }
}

class Point implements Movable {

    private int x;
    private int y;

    Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

    @Override
    public String toString() {
        return "(" + x + ", " + y + ")";
    }

    public void move(int distance) {
        System.out.printf("Movendo o ponto (%d, %d) em %d unidades%n%n", x, y, distance);
        x += distance;
        y += distance;
    }
}

interface Movable {
    void move(int distance);
}

class DebugHandler implements InvocationHandler {

    private Object target;

    public DebugHandler(Object target) {
        this.target = target;
    }

    public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {

        System.out.print(target);
        System.out.print("." + m.getName() + "(");
        if (args != null) {
            for (int i = 0; i < args.length; i++) {
                if (i != args.length - 1) System.out.print(", ");
                System.out.print(args[i]);
            }
        }
        System.out.println(")");

        return m.invoke(target, args);
    }
}

Explicação do Exemplo

  1. A interface Movable define um único método move().
  2. A classe Point implementa essa interface e atualiza suas coordenadas no método move().
  3. O handler DebugHandler intercepta as chamadas e exibe informações sobre os métodos chamados.
  4. O proxy é criado com Proxy.newProxyInstance(), implementando a interface Movable.
  5. As chamadas a proxy.move() são interceptadas pelo handler, que as repassa ao objeto real (Point).

Saída do Programa

(10, 15).move(25)
Movendo o ponto (10, 15) em 25 unidades

(35, 40).move(15)
Movendo o ponto (35, 40) em 15 unidades

(50, 55).move(10)
Movendo o ponto (50, 55) em 10 unidades

Resumo

  • A classe Proxy permite criar objetos dinâmicos que implementam interfaces em tempo de execução.
  • A lógica dos métodos é delegada a um objeto que implementa InvocationHandler.
  • O método invoke() intercepta as chamadas e pode adicionar comportamentos antes ou depois de repassar a execução ao objeto real.
  • Essa técnica é útil para logging, depuração, integração remota e criação de plugins.
Política de Privacidade

Copyright © www.programicio.com Todos os direitos reservados

É proibida a reprodução do conteúdo desta página sem autorização prévia do autor.

Contato: programicio@gmail.com