Proxy Dinâmico em Java

O proxy dinâmico em Java permite estander funcionalidades de objetos sem modificar o código original. A essência está na implementação do mecanismo de proxy, que intercepta chamadas de métodos e adiciona lógica extra.

A seguir, um exemplo demonstrando a criação de um proxy dinâmico. Primeiro, defina uma enterface para o performer:

public interface Entertainer {
    String performSong(String trackName);
    void performDance();
}

Implemente a classe concreta que representa o performer real:

public class RealEntertainer implements Entertainer {
    private String artistName;
    private Integer experienceYears;

    public RealEntertainer(String artistName, Integer experienceYears) {
        this.artistName = artistName;
        this.experienceYears = experienceYears;
    }

    @Override
    public String performSong(String trackName) {
        System.out.println(this.artistName + " está cantando: " + trackName);
        return "Obrigado";
    }

    @Override
    public void performDance() {
        System.out.println(this.artistName + " está dançando");
    }

    public String getArtistName() {
        return artistName;
    }

    public void setArtistName(String artistName) {
        this.artistName = artistName;
    }

    public Integer getExperienceYears() {
        return experienceYears;
    }

    public void setExperienceYears(Integer experienceYears) {
        this.experienceYears = experienceYears;
    }

    @Override
    public String toString() {
        return "RealEntertainer{artistName='" + artistName + "', experienceYears=" + experienceYears + "}";
    }
}

Crie uma classe de fábrica para gerar o prroxy dinâmico:

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

public class DynamicProxyFactory {
    public static Entertainer createProxy(RealEntertainer realPerformer) {
        Entertainer proxy = (Entertainer) Proxy.newProxyInstance(
                DynamicProxyFactory.class.getClassLoader(),
                new Class[]{Entertainer.class},
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxyInstance, Method method, Object[] methodArgs) throws Throwable {
                        if ("performSong".equals(method.getName())) {
                            System.out.println("Preparando microfone, cobrando taxa");
                        } else if ("performDance".equals(method.getName())) {
                            System.out.println("Preparando palco, cobrando taxa");
                        }
                        return method.invoke(realPerformer, methodArgs);
                    }
                }
        );
        return proxy;
    }
}

Para testar o proxy dinâmico:

public class ProxyDemo {
    public static void main(String[] args) {
        RealEntertainer performer = new RealEntertainer("Carlos", 10);
        Entertainer dynamicProxy = DynamicProxyFactory.createProxy(performer);

        String songResult = dynamicProxy.performSong("Samba de Uma Nota Só");
        System.out.println(songResult);

        dynamicProxy.performDance();
    }
}

Tags: java Proxy Dinâmico Reflexão InvocationHandler padrão de projeto

Publicado em 7-9 06:45