Mecanismos de Proxy na AOP do Spring

No framework Spring, a Programação Orientada a Aspectos (AOP) utiliza dois mecanismos principasi de代理 para implementar a interceptação de métodos:

Proxy Dinâmico do JDK: Este mecanismo é utilizado para classes que implemnetam interfaces. O JDK fornece a classe Proxy que permite criar instâncias de proxy em tempo de execução.

Proxy Dinâmico do CGLib: Este mecanismo é aplicado a classes que não implementam qualquer enterface. O CGLib utiliza técnicas de manipulação de bytecode para gerar subclasses dinamicamente, interceptando as chamadas aos métodos da classe pai.

Implementação com Proxy Dinâmico do JDK

O primeiro passo consiste em definir uma interface e sua implementação:


</div><div>```
public class ServicoUsuarioImpl implements SistemaUsuario {
    @Override
    public void autenticar() {
        System.out.println("Método autenticar executado");
    }
    
    @Override
    public void encerrarSessao() {
        System.out.println("Método encerrarSessao executado");
    }
}

public InterceptadorMetodos(Object objetoAlvo) {
    this.objetoAlvo = objetoAlvo;
}

@Override
public Object invoke(Object proxy, Method metodo, Object[] argumentos) throws Throwable {
    System.out.println("Antes da execução do método");
    Object resultado = metodo.invoke(objetoAlvo, argumentos);
    System.out.println("Após a execução do método");
    return resultado;
}

}


</div>Testando a implementação:

<div>```
@Test
public void testarProxyJDK() {
    SistemaUsuario servico = new ServicoUsuarioImpl();
    InterceptadorMetodos manipulador = new InterceptadorMetodos(servico);
    
    SistemaUsuario proxy = (SistemaUsuario) Proxy.newProxyInstance(
        servico.getClass().getClassLoader(),
        servico.getClass().getInterfaces(),
        manipulador
    );
    
    proxy.autenticar();
}

Implementação com CGLib

O JDK Dynamic Proxy possui uma limitação: só pode criar proxies para interfaces. O método newProxyInstance recebe um array de interfaces como segundo parâmetro.

Para classes que não implementam interfaces, o CGLib oferece uma solução eficiente. Esta biblioteca cria subclasses em tempo de execução e utiliza interceptação de métodos para executar código adicional antes e depois das chamadas aos métodos originais.

Criando o代理 do CGLib:

public Object criarProxy(Class classeAlvo) {
    potenciador.setSuperclass(classeAlvo);
    potenciador.setCallback(this);
    return potenciador.create();
}

@Override
public Object intercept(Object objeto, Method metodo, 
        Object[] parametros, MethodProxy proxyMetodo) throws Throwable {
    System.out.println("Pré-processamento CGLib");
    Object resultado = proxyMetodo.invokeSuper(objeto, parametros);
    System.out.println("Pós-processamento CGLib");
    return resultado;
}

}


</div>Testando com CGLib:

<div>```
@Test
public void testarProxyCGLib() {
    CriadorProxyCGLib criador = new CriadorProxyCGLib();
    ServicoUsuarioImpl servicoProxy = (ServicoUsuarioImpl) 
        criador.criarProxy(ServicoUsuarioImpl.class);
    servicoProxy.autenticar();
}

Tags: Spring AOP proxy jdk-dynamic-proxy CGLIB

Publicado em 9-21 11:50