1. Modo de agente
El modelo proxy se llama proxy o sustituto en inglés, y ambos pueden traducirse como "agente" en chino. El llamado proxy significa que una persona o una institución toma medidas en nombre de otra persona u otra institución. En algunos casos, un cliente no quiere o no puede referirse directamente a un objeto, y el objeto proxy puede actuar como un intermediario entre el cliente y el objeto objetivo.
Explicar las diferencias entre varios agentes simplemente simulando el proceso de ejecución de las transacciones
1.1 proxy estático
El código fuente es creado por programadores o se genera automáticamente por herramientas específicas y luego se compila. Antes de que se ejecute el programa, el archivo .class de la clase proxy ya existe.
Interfaz pública PERSONDAOO {Void Saveperson ();} La clase pública PERSONDAOMPL implementa PERSONDAO {@Override public void SavePerson () {System.out.println ("Save Person"); }} Public Class Transaction {void beginTransaction () {System.out.println ("Comenzar la transacción"); } void commit () {system.out.println ("commit"); }}A continuación, escriba una clase de proxy estática --- Implemente la interfaz PERSONDAOO
/*** Clase proxy estática* @author qjc*/public class Personondaoproxy implementa Personondao {Persondao Persondao; Transacción transacción; Pertondaoproxy público (Personondao PERSONDAOO, Transacción Transacción) {this.persondao = Personondao; this.Transaction = Transaction; } @Override public void saveperson () {this.transaction.begintransaction (); this.persondao.saveperson (); this.transaction.commit (); }}prueba
/*** Test proxy estático* @author qjc*/public class testPersonproxy {@test public void testSave () {perseDaoo perseDaoo = new perseDaoMpl (); Transacción transacción = nueva transacción (); PERSONDAOPROXY proxy = new PERSONDAOPROXY (PERSONDAOO, TRANSACCIÓN); proxy.saveperson (); }}Resumir:
1. El modo proxy estático no reutiliza las transacciones
2. Supongamos que hay 100 clases y 100 proxy. ¿Cuántos métodos hay en la interfaz, cuántos métodos deben implementarse en la capa proxy y cuántas transacciones deben abrirse y enviar tantos métodos?
3. Si un proxy implementa múltiples interfaces, si una de las interfaces cambia (se agrega un método), entonces el proxy también debe cambiar en consecuencia.
1.2 JDK proxy dinámico
Clase de proxy dinámico: se crea dinámicamente utilizando el mecanismo de reflexión cuando el programa se está ejecutando.
El proxy dinámico de JDK debe cumplir con cuatro condiciones: 1. Interfaz objetivo 2. Clase objetivo 3. Interceptor 4. Clase de proxy
Uso de la interfaz PERSONDAOO, clase PERSONDAOOMPL y clase de transacción en el ejemplo anterior
Escribe un interceptor
import java.lang.reflect.invocationHandler; import java.lang.reflect.method;/** * Interceptor * 1. Import de clase de destino en * 2. Importar cosas en * 3. Invocar finalización: Inicie las transacciones, llame al método del objeto de destino y cometan transacciones * * * @Author Qjc */CLASE PUBLICA // Target Clase Transaction Transaction Transaction; Interceptor público (objetivo de objeto, transacción de transacción) {this.target = target; this.Transaction = Transaction; } / *** @param instancia proxy de la clase proxy del objeto de destino* @param Método correspondiente a la instancia del método que llama al método de interfaz en la instancia proxy* @param argta la matriz de objeto que se pasa en el método de los valores de parámetros en la instancia de proxy* @return el valor de retorno del método, ningún valor de retorno es null* @throws showle* / public object Invoke (Object Proxy, método, método, método, método, método, método de retorno). {String MethodName = Method.getName (); if ("guardar" .equals (métodeName) || "deleteeperson" .equals (métodeName) || "UpdatePerson" .equals (MethodName)) {this.transaction.begintransaction (); // habilitar el método de transacción.invoke (objetivo); // llamar al método de destino this.transaction.commit (); // Enviar transacción} else {Method.Invoke (Target); } return null; }}prueba
/*** Test Jdk Dynamic Proxy* @author QJC*/public class testjdkproxy {@test public void testSave () {/*** 1. Cree un objeto de destino* 2. Cree una transacción* 3. Cree un interceptor* 4. Genere dinámicamente un objeto proxy*/Object Target = new PersooMpl ();; Transacción transacción = nueva transacción (); Interceptor interceptor = nuevo interceptor (objetivo, transacción); /*** Parámetro 1: Establezca el cargador de clase utilizado por el código, que generalmente usa el mismo cargador de clase que la clase de destino* Parámetro 2: Establezca la interfaz implementada por la clase proxy y use la misma interfaz que la clase de destino* Parámetro 3: Establezca el objeto de devolución de llamada. Cuando se llama al método del objeto proxy, el método de invocación del objeto especificado se llamará*/ perseDao perseDaOo = (perseDao) proxy.newproxyinstance (target.getClass (). GetClassLoader (), target.getClass (). GetInterfaces (), interceptor); PERSONDAOO.SAVEPERSON (); }}Resumir :
1. Debido a que la clase proxy generada por jdkproxy implementa la interfaz, todos los métodos en la clase de destino están incluidos en la clase proxy.
2. Todos los métodos de la clase proxy generada interceptan todos los métodos de la clase de destino. El contenido del método de invocación en el interceptor es exactamente la composición de cada método de la clase proxy.
3. Las interfaces deben existir al usar JDKProxy.
4. Los tres parámetros en el método de invocación pueden acceder a la API del método llamado, los parámetros del método llamado y el tipo de retorno del método llamado de la clase de destino.
defecto:
1. En el interceptor, excepto para llamar al método objetivo del objeto de destino, la función es relativamente única. En este ejemplo, solo se pueden procesar transacciones.
2. La declaración de juicio IF del método de invocación en el interceptor no es confiable en un entorno de desarrollo real, porque una vez que hay muchas declaraciones si es necesario escribirlo.
1.3 proxy dinámico CGLIB
Use la clase PERSONDAOOMPL y la clase de transacción en el ejemplo anterior (sin interfaz)
Escribir clases de interceptor
importar net.sf.cglib.proxy.enhancer; import net.sf.cglib.proxy.methodinterceptor; import net.sf.cglib.proxy.methodproxy;/*** cglib proxy interceptor* @author qjc*/public class interceptor implementsinterceptor {objetivo de objeto privado; // Transacción de transacción privada de clase objetivo proxy; Interceptor público (objetivo de objeto, transacción de transacción) {this.target = target; this.Transaction = Transaction; } / ** * Crear el objeto proxy del objeto de destino * * @return * / public object createProxy () {// Code Mothancement Enhancer mejorador = new mejor (); // Esta clase se usa para generar el objeto proxy potencer.setCallback (esto); // El parámetro es el interceptor potencador.setsuperClass (target.getClass ()); // Establezca el mejor de retorno de la clase principal. // Create a proxy object} /** * @param obj Instance of the target object proxy class* @param method Method instance that calls the parent class method on the proxy instance* @param args An array of objects passed into the method parameter values on the proxy instance* @param methodProxy Use it to call the method of the parent class* @return * @throws Throwable */ public Object intercept(Object obj, Method method, Object[] Args, MethodProxy MethodProxy) lanza lando {this.transaction.begintransaction (); Method.Invoke (Target); this.transaction.commit (); regresar nulo; }}prueba
/*** Test CGLIB Dynamic Proxy* El objeto proxy generado a través de cglib, la clase proxy es una subclase de la clase de destino* @author qjc*/public class testCglibproxy {@test public void testSave () {Object Target = new PersoDaoMpl (); Transacción transacción = nueva transacción (); Interceptor interceptor = nuevo interceptor (objetivo, transacción); PERSONDAOIMPL PERSONDAOMPL = (PERSONDAOMPL) INTERCEPTOR.CREATEPROXY (); PersonondaoImpl.Saveperson (); }}Resumir:
1. CGLIB es una poderosa biblioteca de clases de generación de código de código de alta calidad y de alta calidad. Puede extender las clases de Java e implementar interfaces Java durante el tiempo de ejecución.
2. Use CGLIB para generar una clase proxy como subclase de la clase de destino.
3. No se requiere interfaz para generar clases proxy utilizando CGLIB
4. La clase proxy generada por CGLIB anula los métodos de la clase principal.
5. El contenido del método de intercepción en el interceptor es exactamente la diferencia entre el método del cuerpo CGLIB y el proxy dinámico JDK en la clase proxy:
JDK:
La clase de destino y la clase proxy implementan una interfaz común
El interceptor debe implementar la interfaz Invocathandler, y el contenido del cuerpo del método Invoke en esta interfaz es el contenido del cuerpo del método de objeto proxy.
Cglib:
La clase de destino es la clase principal de la clase proxy
El interceptor debe implementar la interfaz de Interceptor de método, y el método Intercept en la interfaz es el cuerpo del método de la clase proxy, y el mecanismo de mejora del código de bytecodo se utiliza para crear el objeto proxy.
2. Programación orientada orientada
OOP (programación orientada a objetos): encapsulación, herencia, polimorfismo, abstracción
Encapsulación, gestión básica y modular del código. Cada clase puede tener sus propias funciones. Si algo sale mal, solo busque a alguien para discutir el asunto. Desde la perspectiva de la modificación, puede ser riesgoso modificar el código directamente. Esta no es una solución a largo plazo. Lo más natural es cambiar de la encapsulación de tipo. Sin embargo, cómo integrar nuevos tipos y sistemas antiguos, por lo que es necesario establecer una relación de sangre entre las clases. Entonces este es el requisito de herencia. A través de la herencia, puede encontrar que estas clases están relacionadas y existe una relación padre-hijo entre ellas. Luego, sobre la base de la herencia, los polimorfismos tienen características decisivas. Por lo tanto, generalmente se cree que la característica más central de los objetos orientados es en realidad el polimorfismo. Los primeros son todos sentar las bases. El polimorfismo es su característica central. El método de reescritura en la subclase representa la extensión de este nivel, y puede integrarse en el sistema anterior y puede funcionar normalmente. Esta es la reutilización de este nivel, nuevos métodos, sistemas antiguos, extensiones y reutilización.
AOP (programación orientada a la sección):
La programación esencial es una tecnología que agrega dinámicamente funciones a los programas sin modificar el código fuente a través de proxy dinámico de tiempo de ejecución precompilado.
Diferencia entre OOP y AOP:
OOP: la encapsulación abstracta se lleva a cabo en las entidades y sus propiedades y comportamientos del proceso de procesamiento de negocios para obtener una división más clara de unidades lógicas.
AOP: extrae la lógica transversal en el proceso de negocio. Se enfrenta un cierto paso o etapa en el proceso para obtener el bajo efecto de aislamiento de acoplamiento entre las partes del proceso lógico. Estas dos ideas de diseño tienen diferencias esenciales en los objetivos. AOP ha logrado la reutilización de bloques de código.
Mecanismo de proxy de AOP de primavera:
1. Si el objeto objetivo implementa varias interfaces, Spring usa Java.lang.reflect.Proxy de JDK.
Ventajas: debido a que hay una interfaz, el sistema está más libremente acoplado
Desventajas: cree interfaces para cada clase de destino
2. Si el objeto de destino no implementa ninguna interfaz, Spring usa la biblioteca CGLIB para generar una subclase del objeto de destino.
Ventajas: Debido a que la clase proxy y la clase de destino se heredan, no hay necesidad de que exista una interfaz.
Desventajas: debido a que no se usa la interfaz, el acoplamiento del sistema no es tan bueno como el proxy dinámico que usa JDK.
Uso de la interfaz PERSONDAOO, la clase PERSONDAOOMPL y la clase de transacción
Escribir la configuración de Spring
<bean id = "perseDaoo"> </reme> <bean id = "transacción"> </bean> <aop: config> <!-La expresión de puntos de puntos determina la clase de destino-> <aop: punto de punta = "ejecución (* cn.qjc.aop.xml.persondaoImpl.* (..)" id = "realizar"/> <!-reflejo a los puntos de la sección: los puntos de la sección: los puntos: los puntos de la sección: los puntos: los puntos de la sección: los puntos: los puntos de la sección: los puntos: los puntos: los puntos de los puntos: los puntos de la sección: los puntos: los puntos de los puntos: los puntos de la sección: los puntos: los puntos de los puntos: los puntos de la sección: los puntos de la sección: los puntos: los puntos: los puntos de los puntos: los puntos de la sección: los puntos de la sección: los puntos: ref = "Transaction"> <aop: antes del método = "beginTransaction" PointCut-REF = "realizar"/> <aop: después de returación método = "comandante" punto-ref = "realizar"/> </aop: aspecto> </aop: config> </beans>
prueba
/*** Test Spring Dynamic Proxy* @author QJC*/public class TransactionTest {@Test public void testSave () {ApplicationContext context = new ClassPathXMLApPlicationContext ("cn/qjc/aop/xml/applicationContext.xml"); PERSONDAOO PERSONDAOTO = (PERSONDAO) context.getBean ("PERSONDAIO"); PERSONDAOO.SAVEPERSON (); }}Principio de primavera AOP
1. Cuando se inicia el contenedor de resorte, dos frijoles se cargan y se instancian.
2. Cuando el contenedor de resorte analiza el archivo de configuración con <aop: config>, analice la expresión de corte de punto y coincida con los frijoles del contenido del contenedor de resorte de acuerdo con la expresión de corte de puntos.
3. Si la coincidencia es exitosa, cree un objeto proxy para el bean
4. Cuando el cliente usa context.getBean para obtener un objeto, si el objeto tiene un objeto proxy, devuelve el objeto proxy. Si no hay objeto proxy, devuelve el objeto en sí.
Lo anterior es todo el contenido de este artículo. Espero que sea útil para el aprendizaje de todos y espero que todos apoyen más a Wulin.com.