Entrevistador: Ni siquiera entiendo Spring AOP. ¿Debería ir solo o te enviaré?

Prefacio

Debido a las vacaciones, hace tiempo que no lo actualizo. Déjame decirte algo. Durante las vacaciones, un fan me contó sobre su experiencia de abuso. Antes de las vacaciones, fue a una empresa de Internet para una entrevista, pero el entrevistador Spring AOP le preguntó directamente tres veces seguidas. ¡fuerza! En realidad, creo, ¿no es esto bastante simple?

Antes de aprender AOP, si conoce el modelo de agente, será muy fácil de aprender. A continuación, le presentaré este importante punto de conocimiento de AOP.

Modelo de agencia

El modo proxy es un modo de diseño relativamente común en el desarrollo de Java. El propósito del diseño es insertar otras funciones entre la clase de servicio y la clase de cliente. La función insertada es transparente para la persona que llama y juega un papel de control de camuflaje. Ejemplos de casas de alquiler: inquilinos, intermediarios, propietarios. Correspondiente al modelo de agente, a saber: clase de cliente, clase de agente, clase de comisión (clase delegada).

Proporcione un proxy (clase de proxy) para un objeto (clase de delegado) para controlar el acceso a este objeto. La clase delegada y la clase proxy tienen una clase principal o interfaz principal común. La clase de proxy preprocesará y filtrará la solicitud y asignará la solicitud al objeto especificado.

Situaciones de agencia habituales en la vida: agencia de alquiler, empresa de bodas, etc.

Dos principios de diseño del modelo de agencia:

  1. La clase de proxy y la clase de delegación tienen un comportamiento similar (común)
  2. La clase proxy mejora el comportamiento de la clase delegada.

Entrevistador: Ni siquiera entiendo Spring AOP. ¿Debería ir solo o te enviaré?

Modo proxy de uso común:

  1. Proxy estático
  2. Proxy dinámico

Proxy estático

Un objeto proporciona un proxy y la función de proxy es fija para controlar el acceso a este objeto. La clase de proxy y la clase de delegado tienen una clase principal o interfaz principal común, por lo que un objeto de proxy se puede utilizar en cualquier lugar donde se utilice un objeto de clase de delegado. La clase de proxy es responsable del procesamiento previo de la solicitud, el filtrado, el envío de la solicitud a la clase delegada para su procesamiento y el procesamiento posterior después de que la clase delegada ejecuta la solicitud.

Los tres elementos de la agencia

  • Tener un comportamiento común (matrimonio) -interfaz 

  • Función objetivo (recién llegado): comportamiento de logro

  • Función interina (empresa de bodas): lograr la mejora del comportamiento, el comportamiento del objeto objetivo

Características del proxy estático

  1. Rol de destino fijo
  2. Obtenga el rol de destino antes de que se ejecute la aplicación 
  3. El objeto proxy mejora el comportamiento del objeto de destino
  4. Puede haber múltiples agentes, causando una "explosión de clase" (desventajas)

Implementación de proxy estático

Definir comportamiento (comúnmente) definir interfaz

/**
* 定义⾏为
*/
public interface Marry {
 public void toMarry();
}

Público objetivo (comportamiento de implementación)

/**
* 静态代理 ——> ⽬标对象
*/
public class You implements Marry {
 // 实现⾏为
 @Override
 public void toMarry() {
 System.out.println("我要结婚了...");
 }
}

Objeto proxy (implementar comportamiento, mejorar el comportamiento del objeto objetivo)

/**
* 静态代理 ——> 代理对象
*/
public class MarryCompanyProxy implements Marry {
 // ⽬标对象
 private Marry marry;
 // 通过构造器将⽬标对象传⼊
 public MarryCompanyProxy(Marry marry) {
 this.marry = marry;
 }
 // 实现⾏为
 @Override
 public void toMarry() {
 // 增强⾏为
 before();

 // 执⾏⽬标对象中的⽅法
 marry.toMarry();
// 增强⾏为
 after();
 }
 /**
 * 增强⾏为
 */
 private void after() {
 System.out.println("新婚快乐,早⽣贵⼦!");
 }
 /**
 * 增强⾏为
 */
 private void before() {
 System.out.println("场地正在布置中...");
 }
}

Darse cuenta de la función del objeto de destino a través del objeto proxy

// ⽬标对象
You you = new You();
// 构造代理⻆⾊同时传⼊真实⻆⾊
MarryCompanyProxy marryCompanyProxy = new MarryCompanyProxy(you);
// 通过代理对象调⽤⽬标对象中的⽅法
marryCompanyProxy.toMarry();

La función del proxy estático es fija para el proxy. Por ejemplo, hay 20 clases de dao en la capa de dao. Si desea utilizar como proxy los derechos de acceso del método, debe crear 20 funciones de proxy estático en este momento, lo que provoca explosiones de clases y no satisface las necesidades de producción. Esto dio origen a la idea de agencia dinámica.

Proxy dinámico

En comparación con el proxy estático, el proxy dinámico es más flexible en la creación de objetos de proxy. El código de bytes de la clase de proxy dinámico se genera dinámicamente mediante el mecanismo de reflexión de Java cuando el programa se está ejecutando. Creará dinámicamente objetos proxy para el objeto de destino a través del mecanismo de reflexión durante el tiempo de ejecución del programa según sea necesario, sin que el programador escriba manualmente su código fuente. El proxy dinámico no solo simplifica el trabajo de programación, sino que también mejora la escalabilidad del sistema de software, ya que el mecanismo de reflexión puede generar cualquier tipo de clase de proxy dinámico. El comportamiento del agente puede actuar por múltiples métodos, es decir, para satisfacer las necesidades de producción mientras se logra el propósito de un código común.

Dos métodos de implementación de proxy dinámico:

  1. Proxy dinámico JDK
  2. Agente dinámico CGLIB

Características de los agentes dinámicos

  1. El público objetivo no es fijo
  2. Cree objetos de destino de forma dinámica durante la ejecución de la aplicación
  3. El objeto proxy mejora el comportamiento del objeto de destino

Proxy dinámico JDK

Nota: El objeto de destino del proxy dinámico JDK debe tener implementación de interfaz

newProxyInstance

Clase de proxy:

La clase Proxy es una clase de operación que se especializa en proxy. Esta clase se puede usar para generar clases de implementación de manera dinámica para una o más interfaces. Esta clase proporciona los siguientes métodos de operación:

/*
 返回⼀个指定接⼝的代理类的实例⽅法调⽤分派到指定的调⽤处理程序。 (返回代理对象)
 loader:⼀个ClassLoader对象,定义了由哪个ClassLoader对象来对⽣成的代理对象进⾏加载
 interfaces:⼀个Interface对象的数组,表示的是我将要给我需要代理的对象提供⼀组什么接⼝,如果
 我提供了⼀组接⼝给它,那么这个代理对象就宣称实现了该接⼝(多态),这样我就能调⽤这组接⼝中的⽅法了
 h:⼀个InvocationHandler接⼝,表示代理实例的调⽤处理程序实现的接⼝。每个代理实例都具有⼀个关联
的调⽤处理程序。对代理实例调⽤⽅法时,将对⽅法调⽤进⾏编码并将其指派到它的调⽤处理程序的 invoke ⽅法
(传⼊InvocationHandler接⼝的⼦类)
*/
public static Object newProxyInstance(ClassLoader loader,
 Class<?>[] interfaces,
 InvocationHandler h)

Obtener objeto proxy

public class JdkHandler implements InvocationHandler {
 // ⽬标对象
 private Object target; // ⽬标对象的类型不固定,创建时动态⽣成
 // 通过构造器将⽬标对象赋值
 public JdkHandler(Object target) {
 this.target = target;
 }
 /**
 * 1、调⽤⽬标对象的⽅法(返回Object)
 * 2、增强⽬标对象的⾏为
 * @param proxy 调⽤该⽅法的代理实例
 * @param method ⽬标对象的⽅法
 * @param args ⽬标对象的⽅法形参
 * @return
 * @throws Throwable
 */
@Override
 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{
 // 增强⾏为
 System.out.println("==============⽅法前执⾏");
 // 调⽤⽬标对象的⽅法(返回Object)
 Object result = method.invoke(target,args);
 // 增强⾏为
 System.out.println("⽅法后执⾏==============");
 return result;
 }
 /**
 * 得到代理对象
 * public static Object newProxyInstance(ClassLoader loader,
 * Class<?>[] interfaces,
 * InvocationHandler h)
 * loader:类加载器
 * interfaces:接⼝数组
 * h:InvocationHandler接⼝ (传⼊InvocationHandler接⼝的实现类)
 *
 *
 * @return
 */
 public Object getProxy() {
 return
Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterface
s(),this);
 }
}

Darse cuenta de la función del objeto de destino a través del objeto proxy

// ⽬标对象
You you = new You();
// 获取代理对象
JdkHandler jdkHandler = new JdkHandler(you);
Marry marry = (Marry) jdkHandler.getProxy();
// 通过代理对象调⽤⽬标对象中的⽅法
marry.toMarry(); 

Pregunta: ¿Cómo se llama la invocación en la clase de proxy dinámico de Java?

Respuesta: En la clase de proxy dinámica generada $ Proxy0.class, el método de construcción llama al método de construcción de la clase principal Proxy.class, asigna un valor a la variable miembro invocationHandler y crea el método de clase de proxy en el módulo estático de $ Proxy0.class. El método correspondiente llama al método invoke () de la variable miembro InvocationHandler en la clase padre en el cuerpo del método.

Nota: El proxy dinámico de JDK se basa en la implementación de la interfaz. Si algunas clases no tienen implementación de la interfaz, no se puede utilizar el proxy JDK.

Proxy dinámico CGLIB

El mecanismo de proxy dinámico de JDK solo puede proxy de clases que implementan interfaces, y las clases que no pueden implementar interfaces no pueden usar proxy dinámico de JDK. Cglib implementa proxy para clases, y su principio es generar una subclase para la clase de destino especificada. , Y anule el método para lograr la mejora, pero debido a que se hereda, la clase modificada final no se puede usar como proxy.

Agregar dependencia

Introduzca las dependencias de cglib en el archivo pom.xml

<!-- https://mvnrepository.com/artifact/cglib/cglib -->
<dependency>
 <groupId>cglib</groupId>
 <artifactId>cglib</artifactId>
 <version>2.2.2</version>
</dependency>

Clase de definición

Implementar la interfaz MethodInterceptor

public class CglibInterceptor implements MethodInterceptor {
 // ⽬标对象
 private Object target;
 // 通过构造器传⼊⽬标对象
 public CglibInterceptor(Object target) {
 this.target = target;
 }
 /**
 * 获取代理对象
 * @return
 */
 public Object getProxy() {
 // 通过Enhancer对象的create()⽅法可以⽣成⼀个类,⽤于⽣成代理对象
 Enhancer enhancer = new Enhancer();
 // 设置⽗类 (将⽬标类作为其⽗类)
 enhancer.setSuperclass(target.getClass());
 // 设置拦截器 回调对象为本身对象
enhancer.setCallback(this);
 // ⽣成⼀个代理类对象,并返回
 return enhancer.create();
 }
 /**
 * 拦截器
 * 1、⽬标对象的⽅法调⽤
 * 2、增强⾏为
 * @param object 由CGLib动态⽣成的代理类实例
 * @param method 实体类所调⽤的被代理的⽅法引⽤
 * @param objects 参数值列表
 * @param methodProxy ⽣成的代理类对⽅法的代理引⽤
 * @return
 * @throws Throwable
 */
 @Override
 public Object intercept(Object object, Method method, Object[] objects,
 MethodProxy methodProxy) throws Throwable {
 // 增强⾏为
 System.out.println("==============⽅法前执⾏");
 // 调⽤⽬标对象的⽅法(返回Object)
 Object result = methodProxy.invoke(target,objects);
 // 增强⾏为
 System.out.println("⽅法后执⾏==============");
 return result;
 }
}

Método de llamada

// ⽬标对象
You you = new You();
CglibInterceptor cglibInterceptor = new CglibInterceptor(you);
Marry marry = (Marry) cglibInterceptor.getProxy();
marry.toMarry();
User user = new User();
CglibInterceptor cglibInterceptor = new CglibInterceptor(user);
User u = (User) cglibInterceptor.getProxy();
u.test();

La diferencia entre el proxy JDK y el proxy CGLIB

  • Interfaz de implementación de proxy dinámico JDK, ideas de herencia de proxy dinámico Cglib
  • La eficiencia de ejecución del proxy dinámico JDK (cuando el objeto de destino tiene una interfaz) es mayor que la de Ciglib
  • Si el objeto de destino tiene una implementación de interfaz, seleccione JDK proxy, si no hay implementación de interfaz, seleccione Cglib proxy

Primavera AOP

Problemas causados ​​por el procesamiento de registros

Tenemos una Pay (interfaz) y dos clases de implementación DollarPay y RmbPay. Ambas necesitan reescribir el método pay (). En este momento, necesitamos monitorear el desempeño del método de pago, agregar registros, etc. ¿Cómo hacerlo?

Entrevistador: Ni siquiera entiendo Spring AOP. ¿Debería ir solo o te enviaré?

La forma más fácil de pensar

El código de registro se escribe para cada método de carácter, como se muestra a continuación

Entrevistador: Ni siquiera entiendo Spring AOP. ¿Debería ir solo o te enviaré?

Desventajas: demasiada repetición de código, el acoplamiento del código de registro agregado es demasiado alto (si necesita cambiar los requisitos de la función del código de registro de registro, todos los métodos de la clase deben cambiarse y la cantidad de ingeniería es enorme)

Utilice el modo decorador / modo agente para mejorar la solución

Patrón de decorador: agregue dinámicamente algunas responsabilidades adicionales a un objeto.

Modo de agente: acabo de hablar de ello anteriormente. Se deriva la siguiente estructura:

Entrevistador: Ni siquiera entiendo Spring AOP. ¿Debería ir solo o te enviaré?

Después de una cuidadosa consideración, se descubre que aunque el código interno original no se ha cambiado, el procesamiento del registro se realiza para cada clase y se hace referencia a la clase de destino, pero si la cantidad de clases de negocios que se agregarán al registro es grande, entonces implemente manualmente una decoración para cada clase de negocios Se crea la clase de proxy correspondiente y también se aumenta el acoplamiento del código Una vez que cambian los requisitos, se puede imaginar la cantidad de cambios de ingeniería.

¿Existe una solución mejor, siempre que escriba el código una vez, puede reutilizar el código donde desea agregar registros de registro, lograr un acoplamiento suelto y completar la función perfectamente?

La respuesta es sí, existe tal tecnología, ¡y aop ha proporcionado una implementación perfecta para ella!

¿Qué es AOP?

La programación orientada a aspectos es programación orientada a aspectos. En comparación con la programación orientada a objetos de oop, Aop ya no se ocupa de una determinada clase o de algunos métodos en el código del programa, mientras que aop considera más un enfoque cara a cara, a saber Una especie de corte entre capas, por eso se llama superficie de corte. Piense en la hamburguesa de todos (con carne en el medio). Entonces, ¿cómo intercepta aop toda la superficie? Teniendo en cuenta la configuración del filtro de servlets / * aprendida anteriormente, en realidad es la realización de aop.

¿Qué puede hacer AOP?

AOP se utiliza principalmente en registros, estadísticas de rendimiento, control de seguridad, procesamiento de transacciones, etc., para realizar el uso repetido de funciones públicas.

Características de AOP

  1. Reducir el grado de acoplamiento entre módulos y mejorar el grado de agregación de códigos comerciales. (Alta cohesión y bajo acoplamiento)
  2. Reutilización de código mejorada
  3. Reutilización de código mejorada
  4. Se pueden agregar nuevas funciones sin afectar las funciones originales

La implementación subyacente de AOP

Proxy dinámico (JDK + CGLIB)

Conceptos básicos de AOP

Cada punto que se intercepta, el medio del resorte se refiere a cada método que se intercepta, y un punto de conexión del resorte aop representa la ejecución de un método.

Pointcut (punto de entrada)

Para la definición de puntos de conexión de interceptación (las definiciones de reglas coincidentes especifican qué métodos se interceptan y qué métodos se procesan), Spring tiene una definición de lenguaje de expresión especial.

Consejo

Interceptar cada punto de conexión (cada método) después de la operación

  1. Notificación previa (mejora previa): antes () notificación antes de ejecutar el método
  2. Notificación de devolución (mejora de devolución): la notificación después del método afterReturn finaliza normalmente y vuelve
  3. Notificación de lanzamiento de excepción (lanzamiento de excepción mejorado) - afetrThrow ()
  4. Notificación final: después de La notificación se ejecutará independientemente de si el método es anormal o no.
  5. Alrededor de consejos: sobre consejos que rodean un punto de combinación, como una llamada a un método. Este es el tipo de notificación más poderoso. Las notificaciones envolventes pueden completar comportamientos personalizados antes y después de que se llame al método. También elige si continuar la ejecución del punto de conexión o devolver directamente su propio valor de retorno o lanzar una excepción para finalizar la ejecución.

Aspecto

La combinación de punto de entrada y notificación determina la definición del aspecto. El punto de entrada define qué métodos de qué clases se interceptarán. La notificación define qué hacer después de que se intercepta el método. El aspecto es una abstracción de preocupaciones transversales, similar a las clases. , La clase es la abstracción de las características del objeto, y el aspecto es la abstracción de preocupaciones transversales.

Objetivo

Público objetivo

Tejer (tejido en)

El proceso de aplicar el aspecto al objeto de destino y generar el objeto proxy está entretejiendo

Introducción

Sin modificar el código de la aplicación original, el proceso de agregar métodos o campos dinámicamente a la clase durante el tiempo de ejecución del programa se llama importación

Implementación de Spring AOP

Construcción ambiental Spring AOP

Introducción a la dependencia coordinada

<!--Spring AOP-->
<dependency>
 <groupId>org.aspectj</groupId>
 <artifactId>aspectjweaver</artifactId>
 <version>1.8.9</version>
</dependency>

Agregar configuración spring.xml

Agregar espacio de nombres

xmlns:aop="http://www.springframework.org/schema/aop"
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd

Implementación de anotaciones

Definir el aspecto

/**
* 切⾯
* 切⼊点和通知的抽象 (与⾯向对象中的 类 相似)
* 定义 切⼊点和通知 (切⼊点定义了要拦截哪些类的哪些⽅法,通知则定义了拦截过⽅法后要做什么)
*/
@Component // 将对象交给IOC容器去实例化
@Aspect // 声明当前类是⼀个切⾯
public class LogCut {
 /**
 * 切⼊点:
 * 匹配规则。规定什么⽅法被拦截、需要处理什么⽅法
 * 定义切⼊点
 * @Pointcut("匹配规则")
 *
 * Aop 切⼊点表达式简介
 * 1. 执⾏任意公共⽅法:
 * execution(public *(..))
 * 2. 执⾏任意的set⽅法
 * execution(* set*(..))
 * 3. 执⾏com.xxxx.service包下任意类的任意⽅法
 * execution(* com.xxxx.service.*.*(..))
* 4. 执⾏com.xxxx.service 包 以及⼦包下任意类的任意⽅法
 * execution(* com.xxxx.service..*.*(..))
 *
 * 注:表达式中的第⼀个* 代表的是⽅法的修饰范围
 * 可选值:private、protected、public (* 表示所有范围)
 */
 @Pointcut("execution (* com.xxxx.service..*.*(..) )")
 public void cut(){}
 /**
 * 声明前置通知 并将通知应⽤到定义的切⼊点上
 * ⽬标类⽅法执⾏前 执⾏该通知
 *
 */
 @Before(value = "cut()")
 public void before() {
 System.out.println("前置通知.....");
 }
 /**
 * 声明返回通知 并将通知应⽤到定义的切⼊点上
 * ⽬标类⽅法(⽆异常)执⾏后 执⾏该通知
 *
 */
 @AfterReturning(value = "cut()")
 public void afterReturn() {
 System.out.println("返回通知.....");
 }
 /**
 * 声明最终通知 并将通知应⽤到定义的切⼊点上
 * ⽬标类⽅法(⽆异常或有异常)执⾏后 执⾏该通知
 *
 */
 @After(value = "cut()")
 public void after() {
 System.out.println("最终通知.....");
 }
 /**
 * 声明异常通知 并将通知应⽤到定义的切⼊点上
 * ⽬标类⽅法出现异常时 执⾏该通知
 */
 @AfterThrowing(value="cut()",throwing = "e")
 public void afterThrow(Exception e) {
 System.out.println("异常通知....." + " 异常原因:" + e.getCause());
 }
 /**
 * 声明环绕通知 并将通知应⽤到切⼊点上
 * ⽅法执⾏前后 通过环绕通知定义相应处理
 * 需要通过显式调⽤对应的⽅法,否则⽆法访问指定⽅法 (pjp.proceed();)
* @param pjp
 * @return
 */
 @Around(value = "cut()")
 public Object around(ProceedingJoinPoint pjp) {
 System.out.println("前置通知...");
 Object object = null;
 try {
 object = pjp.proceed();
 System.out.println(pjp.getTarget() + "======" + pjp.getSignature());
 // System.out.println("返回通知...");
 } catch (Throwable throwable) {
 throwable.printStackTrace();
 System.out.println("异常通知...");
 }
 System.out.println("最终通知...");
 return object;
 }
}

Archivo de configuración (spring.xml)

<!--配置AOP代理-->
<aop:aspectj-autoproxy/>

Implementación XML

Definir el aspecto

**
* 切⾯
* 切⼊点和通知的抽象 (与⾯向对象中的 类 相似)
* 定义 切⼊点和通知 (切⼊点定义了要拦截哪些类的哪些⽅法,通知则定义了拦截过⽅法后要做什么)
*/
@Component // 将对象交给IOC容器去实例化
public class LogCut02 {
 public void cut(){}
 /**
 * 声明前置通知 并将通知应⽤到定义的切⼊点上
 * ⽬标类⽅法执⾏前 执⾏该通知
 */
public void before() {
 System.out.println("前置通知.....");
 }
 /**
 * 声明返回通知 并将通知应⽤到定义的切⼊点上
 * ⽬标类⽅法(⽆异常)执⾏后 执⾏该通知
 *
 */
 public void afterReturn() {
 System.out.println("返回通知.....");
 }
 /**
 * 声明最终通知 并将通知应⽤到定义的切⼊点上
 * ⽬标类⽅法(⽆异常或有异常)执⾏后 执⾏该通知
 *
 */
 public void after() {
 System.out.println("最终通知.....");
 }
 /**
 * 声明异常通知 并将通知应⽤到定义的切⼊点上
 * ⽬标类⽅法出现异常时 执⾏该通知
 */
 public void afterThrow(Exception e) {
 System.out.println("异常通知....." + " 异常原因:" + e.getCause());
 }
 /**
 * 声明环绕通知 并将通知应⽤到切⼊点上
 * ⽅法执⾏前后 通过环绕通知定义相应处理
 * 需要通过显式调⽤对应的⽅法,否则⽆法访问指定⽅法 (pjp.proceed();)
 * @param pjp
 * @return
 */
 public Object around(ProceedingJoinPoint pjp) {
 System.out.println("前置通知...");
 Object object = null;
 try {
 object = pjp.proceed();
 System.out.println(pjp.getTarget() + "======" + pjp.getSignature());
 // System.out.println("返回通知...");
 } catch (Throwable throwable) {
throwable.printStackTrace();
 System.out.println("异常通知...");
 }
 System.out.println("最终通知...");
 return object;
 }
}

Archivo de configuración (spring.xml)

<!--aop相关配置-->
<aop:config>
 <!--aop切⾯-->
 <aop:aspect ref="logCut02">
 <!-- 定义aop 切⼊点 -->
 <aop:pointcut id="cut" expression="execution(* com.xxxx.service..*.*(..))"/>
 <!-- 配置前置通知 指定前置通知⽅法名 并引⽤切⼊点定义 -->
 <aop:before method="before" pointcut-ref="cut"/>
 <!-- 配置返回通知 指定返回通知⽅法名 并引⽤切⼊点定义 -->
 <aop:after-returning method="afterReturn" pointcut-ref="cut"/>
 <!-- 配置异常通知 指定异常通知⽅法名 并引⽤切⼊点定义 -->
 <aop:after-throwing method="afterThrow" throwing="e" pointcut-ref="cut"/>
 <!-- 配置最终通知 指定最终通知⽅法名 并引⽤切⼊点定义 -->
 <aop:after method="after" pointcut-ref="cut"/>
 <!-- 配置环绕通知 指定环绕通知⽅法名 并引⽤切⼊点定义 -->
 <aop:around method="around" pointcut-ref="cut"/>
 </aop:aspect>
</aop:config>

Resumen de primavera AOP

Los tres elementos del modelo de agente

  1. Definición de interfaz
  2. El objeto de destino y el objeto de proxy deben implementar una interfaz unificada 
  3. El objeto proxy tiene una referencia al objeto de destino, lo que mejora el comportamiento del objeto de destino.

El modo de agente se da cuenta de la clasificación y las diferencias correspondientes

  1. Proxy estático: cree manualmente objetos proxy para el objeto de destino, es decir, complete la creación de objetos proxy en la etapa de compilación del programa
  2. Proxy dinámico: crea dinámicamente el objeto proxy correspondiente al objeto de destino durante el tiempo de ejecución del programa.
  3. Proxy dinámico jdk: el destino del proxy debe implementar un determinado o determinado conjunto de métodos de implementación de interfaz para crear objetos proxy a través de devoluciones de llamada.
  4. Proxy dinámico cglib: el objeto de destino del proxy no necesita implementar la interfaz y se implementa por herencia

En comparación con los agentes estáticos, los agentes dinámicos pueden mejorar la eficiencia del desarrollo, crear agentes en lotes y mejorar la tasa de reutilización del código.

Aop comprensión

  1. Orientado a aspectos, en comparación con oop, se centra en capas o caras en el código 
  2. Desacoplamiento, mejora la escalabilidad del sistema
  3. Mejorar la reutilización del código

Aop Palabras clave

  1. Punto de conexión: todos los métodos
  2. Punto de entrada: una colección de métodos de coincidencia
  3. Aspecto: La colección de puntos de conexión y puntos de entrada determina el aspecto, la abstracción de preocupaciones transversales
  4. Notificación: varias notificaciones
  5. Objeto de destino: el objeto proxy
  6. Weaving: El proceso de aplicar aspectos a los objetos de destino y generar objetos proxy durante el tiempo de ejecución del programa.
  7. Introducción: sin modificar el código original, el proceso de introducir métodos o campos dinámicamente en el programa durante el tiempo de ejecución del programa

Al final

Gracias por ver esto. Corrígeme si hay alguna deficiencia en el artículo. Si crees que el artículo es útil para ti, ¡recuerda darme un Me gusta!

Supongo que te gusta

Origin blog.51cto.com/14801695/2540271
Recomendado
Clasificación