Tipo de notificación de Spring y use ProxyFactoryBean para crear proxy AOP

En " Spring JDK Dynamic Proxy " y " Spring CGLlB Dynamic Proxy ", se explican dos métodos de proxy AOP manual. A continuación se explica  cómo Spring crea el proxy AOP explicando las  notificaciones de Spring .

Tipos de notificaciones de primavera

A través del estudio anterior, podemos saber que el consejo (Consejo) es en realidad el contenido del punto de entrada objetivo. Spring AOP proporciona la interfaz org.aopalliance.aop.Advice para el consejo (Consejo).

Las notificaciones de Spring se pueden dividir en los siguientes cinco tipos según la ubicación del punto de conexión en el método de clase de destino, como se muestra en la Tabla 1.

El nombre Explicación
org.springframework.aop.MethodBeforeAdvice (aviso previo) La notificación que se ejecuta automáticamente antes del método se denomina notificación previa y se puede aplicar a funciones como la gestión de derechos.
org.springframework.aop.AfterReturningAdvice (notificación posterior) Las notificaciones que se ejecutan automáticamente después del método se denominan notificaciones posteriores y se pueden aplicar a funciones como cerrar la secuencia, cargar archivos, eliminar archivos temporales, etc.
org.aopalliance.intercept.MethodInterceptor (notificación envolvente) Las notificaciones que se ejecutan automáticamente antes y después del método se denominan notificaciones envolventes y se pueden aplicar a funciones como el registro y la gestión de transacciones.
org.springframework.aop.ThrowsAdvice (Notificación de excepción) La notificación que se ejecuta automáticamente cuando el método arroja una excepción se denomina notificación de excepción y se puede aplicar a funciones como el manejo de registros de grabación de excepciones.
org.springframework.aop.IntroductionInterceptor (notificación de introducción) Agregue algunos métodos y atributos nuevos a la clase de destino, que se pueden aplicar para modificar la versión anterior del programa (clase mejorada).

 

Declaración de primavera AOP

El método básico de Spring para crear un proxy AOP es usar org.springframework.aop.framework.ProxyFactoryBean. Los puntos de entrada y las notificaciones correspondientes a esta clase proporcionan capacidades de control completas y pueden generar contenido específico.

Las propiedades comúnmente configurables en la clase ProxyFactoryBean se muestran en la Tabla 2.

Nombre del atributo Descripción
objetivo Público objetivo
proxyInterfaces La interfaz que debe implementar el agente. Si hay varias interfaces, puede usar el siguiente formato para asignar valores:
<list>
    <value> </ value>
    ...
</ list>
clase de destino de proxy Si se debe usar el proxy CGLIB para el proxy de clase en lugar de la interfaz, cuando se establece en verdadero
interceptorNames Consejos que necesitan ser implantados
único Si el agente devuelto es un singleton, el valor predeterminado es verdadero (devolver un singleton)
optimizar Cuando se establece en verdadero, CGLIB es obligatorio

En la notificación de primavera, la notificación envolvente es una aplicación muy típica. A continuación se muestra el proceso de creación de proxy AOP en Spring a través del caso de notificación.

1. Importar el paquete JAR

Sobre la base del paquete JAR principal, importe el paquete JAR AOP en el directorio lib del proyecto springDemo03, de la siguiente manera.

  • spring-aop-3.2.13.RELEASE.jar: es la implementación proporcionada por Spring para AOP, que ya se proporciona en el paquete Spring.
  • com.springsource.org.aopalliance-1.0.0.jar:是 AOP 提供的规范,可以在 Spring 的官网网址 https://repo.spring.io/webapp/#/search/quick/ 中进行搜索并下载。

2. 创建切面类 MyAspect

在 src 目录下创建一个名为 com.mengma.factorybean 的包,在该包下创建切面类 MyAspect,如下所示。

package com.mengma.factorybean;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
//需要实现接口,确定哪个通知,及告诉Spring应该执行哪个方法
public class MyAspect implements MethodInterceptor {
    public Object invoke(MethodInvocation mi) throws Throwable {
        System.out.println("方法执行之前");
        // 执行目标方法
        Object obj = mi.proceed();
        System.out.println("方法执行之后");
        return obj;
    }
}

上述代码中,MyAspect 类实现了 MethodInterceptor 接口,并实现了接口的 invoke() 方法。MethodInterceptor 接口是 Spring AOP 的 JAR 包提供的,而 invoke() 方法用于确定目标方法 mi,并告诉 Spring 要在目标方法前后执行哪些方法,这里为了演示效果在目标方法前后分别向控制台输出了相应语句。

3. 创建 Spring 配置文件

在 com.mengma.factorybean 包下创建配置文件 applicationContext.xml,如下所示。 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http:/www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--目标类 -->
    <bean id="customerDao" class="com.mengma.dao.CustomerDaoImpl" />
    <!-- 通知 advice -->
    <bean id="myAspect" class="com.mengma.factorybean.MyAspect" />
    <!--生成代理对象 -->
    <bean id="customerDaoProxy"
     class="org.springframework.aop.framework.ProxyFactoryBean">
     <!--代理实现的接口 -->
        <property name="proxyInterfaces" value="com.mengma.dao.CustomerDao" />
        <!--代理的目标对象 -->
        <property name="target" ref="customerDao" />
        <!--用通知增强目标 -->
        <property name="interceptorNames" value="myAspect" />
        <!-- 如何生成代理,true:使用cglib; false :使用jdk动态代理 -->
        <property name="proxyTargetClass" value="true" />
    </bean>
</beans>

上述代码中,首先配置目标类和通知,然后使用 ProxyFactoryBean 类生成代理对象;第 14 行代码配置了代理实现的接口;第 16 行代码配置了代理的目标对象;第 18 行代码配置了需要植入目标的通知;当第 20 行代码中的 value 属性值为 true 时,表示使用 CGLIB 代理,属性值为 false 时,表示使用 JDK 动态代理。

4. 创建测试类

在 com.mengma.factorybean 包下创建一个名为 FactoryBeanTest 的测试类,编辑后如下所示。 

package com.mengma.factorybean;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.mengma.dao.CustomerDao;
public class FactoryBeanTest {
    @Test
    public void test() {
        String xmlPath = "com/mengma/factorybean/applicationContext.xml";
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
                xmlPath);
        CustomerDao customerDao = (CustomerDao) applicationContext
                .getBean("customerDaoProxy");
        customerDao.add();
        customerDao.update();
        customerDao.delete();
        customerDao.find();
    }
}

5. 运行项目并查看结果

使用 JUnit 测试运行 test() 方法,运行成功后,控制台的输出结果如图 1 所示。 

è¿è¡ç»æ 

发布了203 篇原创文章 · 获赞 6 · 访问量 4500

Supongo que te gusta

Origin blog.csdn.net/weixin_42073629/article/details/105236343
Recomendado
Clasificación