博客
关于我
【Spring AOP】面向切面编程
阅读量:317 次
发布时间:2019-03-04

本文共 2376 字,大约阅读时间需要 7 分钟。

Spring AOP 面向切面编程

一、AOP 理念

面向切面(Aspects)编程是一种增强编程模式,通过 AOP 可以对业务逻辑的各个部分进行隔离,从而降低业务逻辑之间的耦合度,提高程序的可重用性和开发效率。简单来说,就是在不修改源代码的情况下,通过动态代理的方式,在主干代码上添加新的功能。

以登录界面为例:在用户成功登录后,添加权限判断功能。传统方式需要修改源代码,添加权限判断模块,但是在 AOP 下,我们可以通过声明权限判断模块即可使用,不需要时也可不声明。

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

动态代理是 AOP 的核心技术,主要有两种实现方式:JDK 动态代理CGLIB 动态代理

1. JDK 动态代理 — 有接口

JDK 动态代理通过创建接口实现类的代理对象,增强类的方法。以 UserDao 接口为例,login() 方法的实现可以通过 JDK 动态代理在原有功能基础上,添加新的功能。

2. CGLIB 动态代理 — 没有接口

CGLIB 动态代理通过创建子类的代理对象,增强类的方法。以 User 类为例,add() 方法的实现可以通过 CGLIB 动态代理在原有功能基础上,添加新的功能。

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

JDK 动态代理主要通过 Proxy 类实现,以下是实现步骤:

  • 使用 Proxy.newProxyInstance 方法创建代理对象,方法有三个参数:

    • 类加载器
    • 增强方法所在的类(支持多个接口)
    • 实现 InvocationHandler 接口的类,用于增强逻辑
  • 编写 JDK 动态代理代码:

    • 创建接口,定义方法。
    • 创建接口实现类,实现方法。
    • 使用 Proxy 创建代理对象,并通过 InvocationHandler 实现增强逻辑。
  • 以下是一个完整的 JDK 动态代理示例:

    package AOP_JDK动态代理;
    public interface UserDao {
    public int add(int a, int b);
    public String update(String id);
    }
    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;
    }
    }
    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) {
    Class[] interfaces = {UserDao.class};
    UserDaoImpl userDao = new UserDaoImpl();
    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 {
    private Object obj;
    public UserDaoProxy(Object obj) {
    this.obj = obj;
    }
    @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() 获取调用的方法名称,进行不同的处理。
    • invoke 方法中,可以根据方法名称进行逻辑判断,实现更复杂的增强功能。

    以上就是 JDK 动态代理的实现方式,通过动态代理技术,我们可以在不修改源代码的情况下,轻松地对方法进行增强。

    转载地址:http://ofeq.baihongyu.com/

    你可能感兴趣的文章
    Objective-C实现karger算法(附完整源码)
    查看>>
    Objective-C实现KMP搜索算法(附完整源码)
    查看>>
    Objective-C实现Knapsack problem背包问题算法(附完整源码)
    查看>>
    Objective-C实现knapsack背包问题算法(附完整源码)
    查看>>
    Objective-C实现knapsack背包问题算法(附完整源码)
    查看>>
    Objective-C实现knight tour骑士之旅算法(附完整源码)
    查看>>
    Objective-C实现knight Tour骑士之旅算法(附完整源码)
    查看>>
    Objective-C实现KNN算法(附完整源码)
    查看>>
    Objective-C实现knuth morris pratt(KMP)算法(附完整源码)
    查看>>
    Objective-C实现koch snowflake科赫雪花算法(附完整源码)
    查看>>
    Objective-C实现KPCA(附完整源码)
    查看>>
    Objective-C实现KruskalMST最小生成树的算法(附完整源码)
    查看>>
    Objective-C实现kruskal克鲁斯卡尔算法(附完整源码)
    查看>>
    Objective-C实现kth order statistick阶统计量算法(附完整源码)
    查看>>
    Objective-C实现lamberts ellipsoidal distance朗伯椭球距离算法(附完整源码)
    查看>>
    Objective-C实现largest AdjacentNumber最大相邻数算法 (附完整源码)
    查看>>
    Objective-C实现largest subarray sum最大子数组和算法(附完整源码)
    查看>>
    Objective-C实现largestPrime最大素数的算法 (附完整源码)
    查看>>
    Objective-C实现lazy segment tree惰性段树算法(附完整源码)
    查看>>
    Objective-C实现LBP特征提取(附完整源码)
    查看>>