El proxy dinámico es en realidad la clase java.lang.reflect.Proxy que genera dinámicamente un byte de clase en función de todas las interfaces que especifique. Esta clase heredará la clase Proxy e implementará todas las interfaces que especifique (la matriz de interfaces que pase en el parámetro). ); Luego use el cargador de clases que especificó para cargar el byte de clase en el sistema y, finalmente, genere un objeto de dicha clase e inicialice algunos valores del objeto, como invocationHandler, que son los miembros del método correspondientes a todas las interfaces. . Después de la inicialización, el objeto se devuelve al cliente que llama. De esta forma, lo que obtiene el cliente es un objeto Proxy que implementa todas sus interfaces. Consulte el análisis de ejemplo:
interfaz pública BusinessProcessor {
proceso de anulación públicaNegocio();
}
@Anular
proceso de anulación públicaNegocio() {
System.out.println("procesamiento de negocios...");
}
}
importar java.lang.reflect.InvocationHandler;
importar java.lang.reflect.Method;
/**
*Categoría de agencia de negocios
* @autor fanshadoop
*
*/
clase pública BusinessProcessorHandler implementa InvocationHandler {
Objetivo del objeto privado = nulo;
BusinessProcessorHandler (objeto objetivo) {
this.objetivo = objetivo;
}
Invocación pública de objeto (proxy de objeto, método de método, argumentos de objeto [])
lanza arrojable {
salida del sistema
.println("Puedes hacer algo aquí antes de procesar tu negocio");
Resultado del objeto = método.invoke(destino, argumentos);
salida del sistema
.println("Puedes hacer algo aquí después de procesar tu negocio");
resultado de devolución;
}
}
importar java.lang.reflect.Field;
importar java.lang.reflect.Method;
importar java.lang.reflect.Modifier;
importar java.lang.reflect.Proxy;
Prueba de clase pública {
/**
* argumentos @param
*/
público estático vacío principal (String [] argumentos) {
BusinessProcessorImpl bpimpl = nuevo BusinessProcessorImpl();
Controlador BusinessProcessorHandler = nuevo BusinessProcessorHandler (bpimpl);
BusinessProcessor bp = (BusinessProcessor) Proxy.newProxyInstance(
bpimpl.getClass().getClassLoader(), bpimpl.getClass()
.getInterfaces(), controlador);
bp.processBusiness();
System.out.println(bp.getClass().getName());
printClassDefinition(bp.getClass());
}
cadena estática pública getModifier (modificador int) {
Resultado de cadena = "";
cambiar (modificador) {
Modificador de caso.PRIVADO:
resultado = "privado";
Modificador de caso.PÚBLICO:
resultado = "público";
Modificador de caso.PROTEGIDO:
resultado = "protegido";
Modificador de caso.RESUMEN:
resultado = "abstracto";
Modificador de caso.FINAL:
resultado = "final";
Modificador de caso.NATIVO:
resultado = "nativo";
Modificador de caso.ESTÁTICO:
resultado = "estático";
Modificador de caso. SINCRONIZADO:
resultado = "sincronizado";
Modificador de caso.ESTRICT:
resultado = "estricto";
Modificador de caso.TRANSIENTE:
resultado = "transitorio";
Modificador de caso. VOLÁTIL:
resultado = "volátil";
Modificador de caso.INTERFAZ:
resultado = "interfaz";
}
resultado de devolución;
}
public static void printClassDefinition (Clase clz) {
Cadena clzModifier = getModifier(clz.getModifiers());
si (clzModifier! = nulo &&! clzModifier.equals("")) {
clzModificador = clzModificador + " ";
}
Cadena superClz = clz.getSuperclass().getName();
si (superClz != nulo && !superClz.equals("")) {
superClz = "extiende " + superClz;
}
Clase[] interfaces = clz.getInterfaces();
Intersección de cadena = "";
for (int i = 0; i < interfaces.length; i++) {
si (yo == 0) {
inters += "implementos";
}
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.longitud; i++) {
Modificador de cadena = getModifier(fields[i].getModifiers());
if (modificador! = nulo &&! modificador.equals("")) {
modificador = modificador + " ";
}
Cadena nombre del campo = campos[i].getName();
Cadena tipo de campo = campos[i].getType().getName();
System.out.println(" " + modificador + tipo de campo + " " + nombre de campo
+ ";");
}
System.out.println();
Método[] métodos = clz.getDeclaredMethods();
for (int i = 0; i < métodos.longitud; i++) {
Método método = métodos[i];
Modificador de cadena = getModifier(method.getModifiers());
if (modificador! = nulo &&! modificador.equals("")) {
modificador = modificador + " ";
}
Cadena nombre del método = método.getName();
Clase returnClz = método.getReturnType();
Cadena retrunType = returnClz.getName();
Clase[] clzs = método.getParameterTypes();
Cadena paraList = "(";
for (int j = 0; j < clzs.length; j++) {
paraList += clzs[j].getName();
si (j != clzs.longitud - 1) {
paraList += ", ";
}
}
paraList += ")";
clzs = método.getExceptionTypes();
Excepciones de cadena = "";
for (int j = 0; j < clzs.length; j++) {
si (j == 0) {
excepciones += "lanza";
}
excepciones += clzs[j].getName();
si (j != clzs.longitud - 1) {
excepciones += ", ";
}
}
excepciones += ";";
Método de cadena Prototipo = modificador + tipo de retorno + " " + nombre del método
+ paraList + excepciones;
System.out.println(" " + métodoPrototipo);
}
System.out.println("}");
}
}
booleano es igual a (java.lang.Object);
java.lang.String toString();
int código hash();
proceso nuloNegocio();
}
Obviamente, el método Proxy.newProxyInstance hará lo siguiente:
1. Genere dinámicamente una clase basada en las interfaces del segundo parámetro pasadas para implementar la interfaz en las interfaces. En este ejemplo, es el método ProcessBusiness de la interfaz BusinessProcessor. Y hereda la clase Proxy y reescribe tres métodos, como hashcode, toString y equals. Para una implementación específica, consulte ProxyGenerator.generateProxyClass(...); en este ejemplo, se genera la clase $Proxy0.
2. Cargue la clase recién generada en la jvm a través del primer parámetro pasado, classloder. A punto de cargar la clase $Proxy0
3. Utilice el tercer parámetro para llamar al constructor $Proxy0 (InvocationHandler) de $Proxy0 para crear un objeto de $Proxy0, y utilice el parámetro interfaces para recorrer todos sus métodos de interfaz y generar un objeto Método para inicializar varias variables miembro del Método del objeto.
4. Devuelva la instancia de $Proxy0 al cliente.
Está bien ahora. Veamos cómo lo ajusta el cliente y quedará claro.
1. El cliente obtiene el objeto de instancia de $Proxy0. Dado que $Proxy0 hereda BusinessProcessor, no hay problema en convertirlo a BusinessProcessor.
BusinessProcessor bp = (BusinessProcessor)Proxy.newProxyInstance(....);
2. bp.procesoNegocio();
Lo que realmente se llama es $Proxy0.processBusiness(); entonces la implementación de $Proxy0.processBusiness() es llamar al método de invocación a través de InvocationHandler.