Charla divertida sobre Spring AOP

1. Qué es AOP

La AOP (Programación Orientada a Aspectos), es decir, la programación orientada a aspectos , se complementa con OOP (Programación Orientada a Objetos, Programación Orientada a Objetos) y proporciona una configuración de software de OOP abstracta de perspectiva diferente.
En OOP, usamos class como nuestra unidad básica, mientras que la unidad básica en AOP es Aspect.

2. El concepto básico de AOP

  1. Aspecto (Aspecto) : generalmente una clase, que puede definir accesos directos y notificaciones
  2. JointPoint : un punto claro durante la ejecución del programa, generalmente una llamada a un método
  3. Consejo (información / mejora) : AOP realiza un procesamiento mejorado en un punto de entrada específico, incluso antes, después, después de la devolución, después de la tirada,
  4. Pointcut (pointcut) : es el punto de conexión con notificación, que se refleja principalmente en la escritura de la expresión de pointcut en el programa
  5. Proxy AOP : el objeto creado por el marco AOP, y el proxy es la mejora del objeto de destino. En Spring AOP, el proxy puede ser un proxy dinámico JDK, el proxy puede ser una interfaz basada en CGLIB, que se basa en la subclase
    s

3. ¿Cómo jugar con AOP?

Las tecnologías para implementar AOP se dividen principalmente en dos categorías:

1. Adopte la tecnología de proxy dinámico para decorar el mensaje interceptando el mensaje para reemplazar la ejecución del comportamiento del objeto original;

El segundo es utilizar el tejido estático , introduciendo una sintaxis específica para crear "aspectos", de modo que el compilador pueda tejer código relacionado con "aspectos" durante la compilación.

Nos centramos en la tecnología de proxy dinámico en la implementación de la capa inferior de AOP:
1) Proxy JDK: el proxy basado en interfaz debe basarse en la interfaz y generará subobjetos del tipo de interfaz del objeto de destino.
2) Proxy Cglib: Proxy basado en clases, no necesita basarse en la interfaz, generará subobjetos del tipo de objeto de destino.
Consejos: [Agente] En la vida, es más como un corredor o intermediario.

4. Hablar de proxy dinámico (piratería)

  1. jdk hacker: solo puede invadir objetos que implementan interfaces. Para la clase de implementación de interfaz. [Tecnología de proxy dinámico JDK]
Código:

1) Defina una interfaz UserDao:

package com.lq.dao;
public interface UserDao {
    
    
     int add(int a, int b);
}

2) Clase de implementación de la interfaz UserDao:

package com.lq.dao.impl;
import com.lq.dao.UserDao;
public class UserDaoImpl implements UserDao {
    
    
    //add方法:实现a+b的值
    public int add(int a, int b) {
    
    
        return a+b;
    }
}

3) Definir una clase JdkHk (hacker JDK)

package com.lq.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import javax.management.loading.PrivateClassLoader;
import com.lq.dao.UserDao;

/*
 * 黑客类 :(证--规范--接口:一组功能的约定)
 */
public class JdkHk implements InvocationHandler{
    
    
	//目标对象
	private Object target;
	public JdkHk(UserDao userDao) {
    
    
		this.target=userDao;
	}
    /**
     * 黑客类入侵的方法
     * proxy:代理对象
     * method:入侵的目标的方法
     * args:入侵的目标的方法的参数
     */
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
    
		System.out.println("黑客开始入侵!!");
		//干坏事(在这里我们可以通过修改参数,来控制最后结果的输出!结果为:1+2=3)
		args[0]=1;
		args[1]=2;
		//调用目标方法
		Object result = method.invoke(target, args);
		System.out.println("黑客入侵接结束");
		return result;
	}    
}

4) Definir una clase de prueba Prueba

package com.lq.proxy;
import java.lang.reflect.Proxy;
import com.lq.dao.UserDao;
import com.lq.dao.impl.UserDaoImpl;
public class Test01 {
    
    
    public static void main(String[] args) {
    
    
  //客户端---调用目标类(UserDaoImpl)的目标方法add方法
//        UserDao userDao = new UserDaoImpl();
//        int result = userDao.add(3, 5);
//        System.out.println("result==>:"+result);
        
        //目标对象
    	UserDao target=new UserDaoImpl();
        //黑客对象
    	JdkHk jdkHk=new JdkHk(target);
        //代理对象
        /*
         * loader             类加载器
         * ClassLoader.getSystemClassLoader() 获取当前程序的类加载器
         * interfaces       目标的实现的接口class
         * h                     invocationHandler对象--黑客对象
         * 字节码拼接技术
         */
        UserDao userDao = (UserDao)Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[] {
    
    UserDao.class}, jdkHk);
        //客户端
        int result = userDao.add(55, 22);
        System.err.println("结果为===》"+result);
        
    }
}

5) El resultado de salida es:
Inserte la descripción de la imagen aquí

2. Spring hacker: para la clase (paquete de aspectos, proporcionado por Spring).
aopalliance: MethodInteceptor es un hacker jdk que se usa internamente cuando la clase implementa la interfaz; si la clase no implementa la interfaz, use el proxy dinámico cglib .

Código:

1) Definir una clase UserDaoImpl

package com.lq.dao.impl;
public class UserDaoImpl {
    
    
	public int add(int a,int b) {
    
    
		System.out.println("调用UserDaoImpl的add方法");
		return a+b;
		
	}
}

2) Defina un objeto SpringHk:

package com.lq.proxy;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class SpringHk implements MethodInterceptor{
    
    
	/**
	 * invocation :目标对象的目标方法
	 */	
	@Override
	public Object invoke(MethodInvocation invocation) throws Throwable {
    
    
		System.out.println("1、鉴权");
		//调用目标方法
		Object result=invocation.proceed();
		System.out.println("1、日志留痕");
		return result;
	}
}
  1. Configure el archivo spring_beans.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
        https://www.springframework.org/schema/beans/spring-beans.xsd">

	<!--1、目标对象 -->
	<bean id="userDao" class="com.lq.dao.impl.UserDaoImpl">
	</bean>

	<!-- 2、Spring黑客对象 -->
	<bean id="springHk" class="com.lq.proxy.SpringHk">

	</bean>
	<!-- 3、代理对象 -->
	<bean id="userDaoProxy"
		class="org.springframework.aop.framework.ProxyFactoryBean">
		<!-- 3.1目标对象 -->
		<property name="target" ref="userDao"></property>
		<!-- 3.2黑客对象 -->
		<property name="interceptorNames">
			<array>
				<value>springHk</value>
			</array>
		</property>
	</bean>
</beans>

4) Escriba la clase de prueba SpringHkTest.java

package com.lq.proxy;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.lq.dao.impl.UserDaoImpl;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring-beans.xml")
public class SpringHkTest {
    
    

	@Autowired // 默认按类型注入,通过@Qualifier修改为按名称注入
	@Qualifier("userDaoProxy")
	private UserDaoImpl userDao;

	@Test
	public void test01() {
    
    
		System.out.println(userDao.add(22, 22));
	}
}

  1. Los resultados de la prueba son:
    Inserte la descripción de la imagen aquí

Resumen : puede utilizar un proxy dinámico JDK (clase de interfaz de implementación) o un proxy dinámico Cglib (clase o clase de interfaz de implementación)

Supongo que te gusta

Origin blog.csdn.net/weixin_46822085/article/details/108856464
Recomendado
Clasificación