O proxy dinâmico é na verdade a classe java.lang.reflect.Proxy que gera dinamicamente um byte de classe com base em todas as interfaces que você especificar. Esta classe herdará a classe Proxy e implementará todas as interfaces que você especificar (a matriz de interface que você passa no parâmetro). ); Em seguida, use o carregador de classe especificado para carregar o byte da classe no sistema e, finalmente, gere um objeto dessa classe e inicialize alguns valores do objeto, como invocationHandler, que são os membros do método correspondentes a todas as interfaces. . Após a inicialização, o objeto é retornado ao cliente chamador. Desta forma, o que o cliente obtém é um objeto Proxy que implementa todas as suas interfaces. Por favor, veja o exemplo de análise:
interface pública BusinessProcessor {
public void processBusiness();
}
@Substituir
public void processBusiness() {
System.out.println("processando negócios....");
}
}
importar java.lang.reflect.InvocationHandler;
importar java.lang.reflect.Method;
/**
*Categoria agência comercial
* @autor fanshadoop
*
*/
classe pública BusinessProcessorHandler implementa InvocationHandler {
destino do objeto privado = null;
BusinessProcessorHandler(alvo do objeto) {
este.target = alvo;
}
invocação de objeto público (proxy de objeto, método de método, objeto [] args)
lança Arremessável {
Sistema.out
.println("Você pode fazer algo aqui antes de processar seu negócio");
Resultado do objeto = método.invoke(target, args);
Sistema.out
.println("Você pode fazer algo aqui depois de processar seu negócio");
resultado de retorno;
}
}
importar java.lang.reflect.Field;
importar java.lang.reflect.Method;
importar java.lang.reflect.Modifier;
importar java.lang.reflect.Proxy;
teste de classe pública {
/**
* @param argumentos
*/
public static void main(String[] args) {
BusinessProcessorImpl bpimpl = new BusinessProcessorImpl();
Manipulador BusinessProcessorHandler = novo BusinessProcessorHandler(bpimpl);
BusinessProcessor bp = (BusinessProcessor) Proxy.newProxyInstance(
bpimpl.getClass().getClassLoader(), bpimpl.getClass()
.getInterfaces(), manipulador);
bp.processBusiness();
System.out.println(bp.getClass().getName());
printClassDefinition(bp.getClass());
}
public static String getModifier(int modificador) {
Resultado da string = "";
mudar (modificador) {
modificador de caso.PRIVATE:
resultado = "privado";
modificador de caso.PÚBLICO:
resultado = "público";
Modificador de caso.PROTEGIDO:
resultado = "protegido";
modificador de caso.RESUMO:
resultado = "resumo";
Modificador de caso.FINAL:
resultado = "final";
modificador de caso.NATIVE:
resultado = "nativo";
modificador de caso.STATIC:
resultado = "estático";
Modificador de caso.SYNCHRONIZED:
resultado = "sincronizado";
modificador de caso.STRICT:
resultado = "estrito";
Modificador de caso.TRANSIENT:
resultado = "transitório";
Modificador de caso.VOLATILE:
resultado = "volátil";
modificador de caso.INTERFACE:
resultado = "interface";
}
resultado de retorno;
}
public static void printClassDefinition(Classe clz) {
String clzModifier = getModifier(clz.getModifiers());
if (clzModifier != null && !clzModifier.equals("")) {
clzModificador = clzModificador + " ";
}
String superClz = clz.getSuperclass().getName();
if (superClz != null && !superClz.equals("")) {
superClz = "estende" + superClz;
}
Classe[] interfaces = clz.getInterfaces();
String inters = "";
for (int i = 0; i < interfaces.length; i++) {
se (eu == 0) {
inters += "implementa";
}
inters += interfaces[i].getName();
}
System.out.println(clzModifier + clz.getName() + " " + superClz + " "
+ inters);
System.out.println("{");
Campo[] campos = clz.getDeclaredFields();
for (int i = 0; i <campos.comprimento; i++) {
Modificador de string = getModifier(fields[i].getModifiers());
if (modificador! = null &&! modifier.equals("")) {
modificador = modificador + " ";
}
String nomeDoCampo = campos[i].getNome();
String fieldType = campos[i].getType().getName();
System.out.println(" " + modificador + fieldType + " " + fieldName
+ ";");
}
System.out.println();
Método[] métodos = clz.getDeclaredMethods();
for (int i = 0; i < métodos.length; i++) {
Método método = métodos[i];
Modificador de string = getModifier(method.getModifiers());
if (modificador! = null &&! modifier.equals("")) {
modificador = modificador + " ";
}
String nomeMetodo = método.getNome();
Classe returnClz = método.getReturnType();
String retrunType = returnClz.getName();
Classe[] clzs = método.getParameterTypes();
String paraLista = "(";
for (int j = 0; j < clzs.length; j++) {
paraList += clzs[j].getNome();
if (j! = clzs.length - 1) {
paraLista += ", ";
}
}
paraLista += ")";
clzs = método.getExceptionTypes();
Exceções de string = "";
for (int j = 0; j < clzs.length; j++) {
se (j == 0) {
exceções += "lança";
}
exceções += clzs[j].getName();
if (j! = clzs.length - 1) {
exceções += ", ";
}
}
exceções += ";";
String methodPrototype = modificador + retrunType + " " + methodName
+ paraList + exceções;
System.out.println(" " + métodoProtótipo);
}
System.out.println("}");
}
}
booleano é igual (java.lang.Object);
java.lang.String toString();
int hashCode();
void processBusiness();
}
Obviamente, o método Proxy.newProxyInstance fará o seguinte:
1. Gere dinamicamente uma classe com base nas interfaces do segundo parâmetro passado para implementar a interface em interfaces. Neste exemplo, é o método processBusiness da interface BusinessProcessor. E herda a classe Proxy e reescreve três métodos, como hashcode, toString e equals. Para implementação específica, consulte ProxyGenerator.generateProxyClass(...); Neste exemplo, a classe $Proxy0 é gerada.
2. Carregue a classe recém-gerada na jvm por meio do primeiro parâmetro passado, classloder. Prestes a carregar a classe $Proxy0
3. Use o terceiro parâmetro para chamar o construtor $Proxy0 (InvocationHandler) de $Proxy0 para criar um objeto de $Proxy0 e use o parâmetro interfaces para percorrer todos os seus métodos de interface e gerar um objeto Method para inicializar várias variáveis membro do Method do objeto.
4. Retorne a instância de $Proxy0 ao cliente.
Está tudo bem agora. Vamos ver como o cliente ajusta e isso ficará claro.
1. O cliente obtém o objeto de instância de $Proxy0. Como $Proxy0 herda BusinessProcessor, não há problema em convertê-lo para BusinessProcessor.
BusinessProcessor bp = (BusinessProcessor)Proxy.newProxyInstance(....);
2. bp.processBusiness();
O que realmente é chamado é $Proxy0.processBusiness(); então a implementação de $Proxy0.processBusiness() é chamar o método de invocação através de InvocationHandler!