As classes de proxy dinâmicas de Java podem ser divididas em dois tipos.
Proxy estático: criado por programadores ou gera automaticamente o código -fonte por ferramentas específicas e o compila. Antes da execução do programa, já existe o arquivo .class da classe proxy.
Proxy dinâmico: é criado dinamicamente usando o mecanismo de reflexão quando o programa está em execução.
1. Primeiro, demonstraremos o proxy dinâmico Java.
Agora temos uma interface de negócios simples dizendo, como segue:
A cópia do código é a seguinte:
pacote testaop;
interface pública dizendo {
public void dizhello (nome da string);
public void Talking (nome da string);
}
Uma simples classe de implementação SweenImpl, da seguinte maneira:
A cópia do código é a seguinte:
pacote testaop;
classe pública Sayspl implementa dizendo {
@Override
public void dizhello (nome da string) {
// TODO Method Stub
System.out.println (nome + ": Olá a todos!");
}
@Override
public void Talking (Nome da String) {
// TODO Method Stub
System.out.println (nome + ": quero dizer, devemos trabalhar duro para construir uma sociedade harmoniosa!");
}
}
O que queremos alcançar é implantar dinamicamente o processamento antes e depois de dizerhello e conversar.
O proxy dinâmico do JDK usa principalmente duas classes no pacote java.lang.reflect: Proxy e InvocationHandler.
A InvocationHandler é uma interface que define a lógica cruzada implementando essa interface e chama o código da classe de destino por meio de um mecanismo de reflexão, tece dinamicamente a lógica de corte cruzado e a lógica de negócios.
O Proxy usa o InvocationHandler para criar dinamicamente uma instância que se conforme em uma determinada interface e gera um objeto proxy da classe de destino.
Da seguinte maneira, criamos uma instância da InvocationHandler:
A cópia do código é a seguinte:
pacote testaop;
importar java.lang.reflect.invocationHandler;
importar java.lang.reflect.method;
classe pública MyInvocationHandler implementa InvocationHandler {
destino de objeto privado;
MyInvocationHandler (destino do objeto) {
this.target = Target;
}
@Override
Public Object Invoke (proxy do objeto, método do método, objeto [] args)
lances lançáveis {
// executar antes do método de destino
System.out.println (" - - - - - - - - - - - - - - - - - - - - -");
System.out.println ("Por favor, fale no palco próxima pessoa!");
// CHAMADA DE Método de destino
Objeto obj = métod.invoke (alvo, args);
// executar o método de destino depois
System.out.println ("Todos aplausos e incentivo!");
retornar obj;
}
}
Aqui está o teste:
A cópia do código é a seguinte:
pacote testaop;
importar java.lang.reflect.proxy;
classe pública jdkproxytest {
public static void main (string [] args) {
// A categoria de negócios de destino que você deseja ser agente
Dizendo alvo = novo sweayImpl ();
// tecer a classe de destino e a classe cruzada juntos
MyInvocationHandler Handler = new MyInvocationHandler (Target);
// Crie uma instância de proxy
Dizendo proxy = (dizendo) proxy.newproxyInstance (
Target.getClass (). getClassloader (), // O carregador de classe da classe de destino
Target.getClass (). getInterfaces (), // interfaces da classe de destino
manipulador); // classe cruzada
proxy.sayhello ("Xiao Ming");
proxy.Talking ("Xiaoli");
}
}
A operação é a seguinte:
A cópia do código é a seguinte:
―S
Por favor, fale no palco da próxima pessoa!
Xiao Ming: Olá a todos!
Todos aplaudidos e encorajados!
―S
Por favor, fale no palco da próxima pessoa!
Xiaoli: Quero dizer, devemos trabalhar duro para construir uma sociedade harmoniosa!
Todos aplaudidos e encorajados!
Há uma grande limitação para o uso de proxy dinâmico do JDK, que é que ele exige que a classe de destino implemente a interface do método correspondente e só possa criar instâncias de proxy para a interface. Podemos ver no método de proxy NewProxyInstance na classe de teste acima de que o segundo parâmetro desse método é a interface da classe de destino. Se esta classe não implementar uma interface, depende do proxy dinâmico do CGLIB.
O CGLIB adota a tecnologia ByteCode muito subjacente, que pode criar uma subclasse para uma classe e usar técnicas de interceptação do método na subclasse para interceptar todas as chamadas dos métodos de classe pai e implantar a lógica cruzada na situação.
2. Em seguida, demonstraremos o proxy dinâmico do CGLIB.
Primeiro, precisamos orientar o pacote.
Primeiro, criamos um criador de proxy CGlibProxy:
A cópia do código é a seguinte:
pacote testaop.cglib;
importar java.lang.reflect.method;
importação net.sf.cglib.proxy.enhancer;
importação net.sf.cglib.proxy.methodintercept;
importação net.sf.cglib.proxy.methodProxy;
classe pública CGLIBProxy implementa MethodInterceptor {
Intensificador intensificador = new intensancer ();
Public Object getProxy (classe clazz) {
// defina a subclasse a ser criada
aprimor.SetSuperclass (clazz);
intensificador.setCallback (this);
// Crie dinamicamente instâncias de subclasse através da tecnologia ByteCode
return aprimor.create ();
}
@Override
interceptação pública de objeto (objeto obj, método de método, objeto [] args,
MethodProxy Proxy) lança arremesso {
// TODO Method Stub
System.out.println (" - - - - - - - - - - - - - - - - - - - - -");
System.out.println ("Por favor, fale no palco próxima pessoa!");
// CHAMADA DE Método de destino
Resultado do objeto = proxy.invokesuper (obj, args);
// executar o método de destino depois
System.out.println ("Todos aplausos e incentivo!");
resultado de retorno;
}
}
Em seguida, teste:
A cópia do código é a seguinte:
pacote testaop.cglib;
importar testaop.ying;
importar testaop.sayingImpl;
classe pública CglibProxytest {
public static void main (string [] args) {
CGLIBPROXY proxy = new CGlibProxy ();
// Crie classes de proxy gerando dinamicamente subclasses
Dizendo alvo = (dizendo) proxy.getProxy (sweayImpl.class);
Target.Sayhello ("Xiao Ming");
Target.Talking ("Xiaoli");
}
}
O resultado não é diferente do proxy dinâmico do JDK.
Tanto o proxy dinâmico do JDK quanto o proxy dinâmico do CGLIB são aprimoramentos de tempo de execução, que são aprimorados pela implantação de código cruzado em classes de proxy. Ao contrário disso, o aspecto, que pode implantar o código cruzado no período de compilação por meio de um compilador especial.