Para criar um proxy dinâmico em Java, é necessário seguir algumas etapas que envolvem interfaces, classes de implementação e manipuladores de invocação. Abaixo, detalho o processo com exemplos de código modificados para maior clareza.
1. Definição da Interface e Classe de Implementação
Primeiro, define-se uma interface que declara os métodos a serem delegados, seguida por uma classe concreta que implementa essa interface. Essa classe concreta é o objeto que será substituído pelo proxy.
Exemplo de interface:
public interface ServicoUsuario { void registrar(Usuario usuario); }
</div>Classe de implementação (objeto a ser delegado):
<div>```
package proxy.dinamico.exemplo;
public class ServicoUsuarioMySQL implements ServicoUsuario {
@Override
public void registrar(Usuario usuario) {
System.out.println("Conectando ao banco de dados MySQL...");
System.out.println("Usuário com ID " + usuario.getId() + " adicionado com sucesso.");
}
}
Em seguida, implementa-se uma classe que implementa a interface InvocationHandler. Essa classe conterá a lógica adicional a ser executada antes ou após a chamada do método original.
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method;
public class ManipuladorAuditoria implements InvocationHandler { private final Object alvo;
public ManipuladorAuditoria(Object alvo) {
this.alvo = alvo;
}
@Override
public Object invoke(Object proxy, Method metodo, Object[] argumentos) throws Throwable {
System.out.println("Iniciando auditoria: método de registro em execução...");
Object resultado = metodo.invoke(alvo, argumentos);
System.out.println("Finalizando auditoria: método de registro concluído.");
return resultado;
}
}
</div>A razão para implementar `InvocationHandler` é que, ao chamar um método no proxy, a execução é redirecionada para o método `invoke` desta classe, permitindo interceptar e personalizar o comportamento.
#### 3. Uso do Proxy Dinâmico para Chamar Métodos
Por fim, utiliza-se a classe `Proxy` para criar uma instância de proxy que delega chamadas ao objeto real através do manipulador.
<div>```
package proxy.dinamico.exemplo;
import java.lang.reflect.Proxy;
public class TesteProxyDinamico {
public static void main(String[] args) {
ServicoUsuario servicoReal = new ServicoUsuarioMySQL();
ManipuladorAuditoria manipulador = new ManipuladorAuditoria(servicoReal);
ServicoUsuario proxyServico = (ServicoUsuario) Proxy.newProxyInstance(
servicoReal.getClass().getClassLoader(),
servicoReal.getClass().getInterfaces(),
manipulador
);
proxyServico.registrar(new Usuario("001"));
}
}
- Primeiro parâmetro: ClassLoader do objeto original, necessário para carregar classes do proxy.
- Segundo parâmetro: Array de interfaces que o proxy deve implementar.
- Terceiro parâmetro: Instância de
InvocationHandlerque processará as chamadas de métodos.
Fluxo de execução do proxy:
- Ao invocar
registrarno proxy, o método não chama diretamente a implementação real. - Em vez disso, o proxy redireciona a chamada para o método
invokedoManipuladorAuditoria. - Dentro de
invoke, a lógica adicional é executada, e o método original do objeto real é chamado viametodo.invoke.
Assim, o uso das classes InvocationHandler e Proxy é essencial para implementar proxies dinâmicos em Java.