【Spring AOP】面向切面编程



Spring AOP 面向切面编程

一、AOP理念

在这里插入图片描述

  • 面向切面(方面)编程,利用 AOP 可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

  • 简单的来说就是:用不修改源代码的方式,在主干上添加新的功能实现。

  • 以登陆界面为例:
    在这里插入图片描述
    在进行成功登陆后我们添加权限判断的功能,按照原来的方式,需要修改源代码,去添加权限判断功能。但是利用AOP理念,我们添加一个权限判断模块,需要时声明即可;不需要时,也可不声明。

返回顶部


二、AOP底层原理 — 动态代理

① JDK动态代理 — 有接口

  • 创建接口实现类代理对象,增强类的方法
    在这里插入图片描述
    当我们有接口UserDao,并且含有方法login()。一般就是通过创建其实现类重写方法进行功能实现,现在通过JDK动态代理,创建UserDao接口实现类的代理对象,在原有的功能基础之上,再添加新的功能

② CGLIB动态代理 — 没有接口

  • 创建子类的代理对象,增强类的方法
    在这里插入图片描述
    当我们没有接口,只有类User,并且含有方法add()。一般就是通过创建子类继承自User类,在方法体内部使用super关键字调用父类的方法,并对其进行完善,但是通过CGLIB动态代理,我们创建当前类的子类代理对象来进行完善

返回顶部


三、AOP底层原理 — JDK动态代理实现

1、使用 JDK 动态代理,使用 Proxy 类里面的方法创建代理对象
在这里插入图片描述

  • (1)调用 newProxyInstance 方法
    在这里插入图片描述
    方法有三个参数:
    • 第一参数,类加载器
    • 第二参数,增强方法所在的类,这个类实现的接口,支持多个接口
    • 第三参数,实现这个接口 InvocationHandler,创建代理对象,写增强的部分
      在这里插入图片描述

2、编写 JDK 动态代理代码

  • (1)创建接口,定义方法
package AOP_JDK动态代理;

public interface UserDao {
    
    
    public int add(int a,int b);
    public String update(String id);
}

  • (2)创建接口实现类,实现方法
package AOP_JDK动态代理;

public class UserDaoImpl implements UserDao {
    
    
    @Override
    public int add(int a, int b) {
    
    
        System.out.println("add方法执行了...");
        return a+b;
    }

    @Override
    public String update(String id) {
    
    
        System.out.println("update方法执行了...");
        return id;
    }
}

  • (3)使用 Proxy 类创建接口代理对象
package AOP_JDK动态代理;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;

public class JDKProxy {
    
    
    public static void main(String[] args) {
    
    
        // 3.创建接口实现类代理对象
        // 3.1 增强方法所在的类,支持多接口
        Class[] interfaces = {
    
    UserDao.class};
        // 3.2 创建接口实现类对象
        UserDaoImpl userDao = new UserDaoImpl();
        // 3.3 创建代理对象 --- 类加载器、增强方法所在类、实现接口 InvocationHandler,创建代理对象,写增强的部分
        UserDao dao = (UserDao) Proxy.newProxyInstance(JDKProxy.class.getClassLoader(),interfaces,new UserDaoProxy(userDao));
        // 通过代理对象调用增强方法
        int result = dao.add(1,2);
        System.out.println("result:"+result);
    }
}
class UserDaoProxy implements InvocationHandler{
    
    

    // 1.获取代理对象的来源 --- 通过有参构造器进行传递
    private Object obj;
    public UserDaoProxy(Object obj){
    
    
        this.obj = obj;
    }

    // 2.增强的逻辑
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
    

        // 方法之前进行处理
        System.out.println("方法之前进行处理..."+method.getName()+":传递的参数..."+ Arrays.toString(args));

        // 被增强的方法执行
        Object result = method.invoke(obj,args);

        // 方法之后进行处理
        System.out.println("方法之后进行处理..."+obj);

        return result;
    }
}

在这里插入图片描述
补充:

  • 如果有多个方法,可以通过method.getName()获取调用的方法名称,然后相应的做出不同的处理。
  // 2.增强的逻辑
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
    

        if(method.getName().equals("add"){
    
    
	        // 方法之前进行处理
	        System.out.println("方法之前进行处理..."+method.getName()+":传递的参数..."+ Arrays.toString(args));
	        // 被增强的方法执行
	        Object result = method.invoke(obj,args);
	        // 方法之后进行处理
	        System.out.println("方法之后进行处理..."+obj);

     	    return result;
        } else {
    
    
            ............
    }

返回顶部


猜你喜欢

转载自blog.csdn.net/qq_45797116/article/details/113776727
今日推荐