文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Spring AOP底层原理及代理模式

2024-04-02 19:55

关注

Spring AOP底层原理代理模式

一、什么是 AOP

AOP 就是面向切面编程,是 OOP(面向对象编程)的延续。

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

通俗一点说,不用修改原代码,可以给原代码增加新的功能。

二、AOP 底层原理

AOP 底层原理是使用动态代理。

那代理是什么?有动态代理,那是不是还有静态代理?

1. 什么是代理?

就是为一个目标对象提供一个代理对象,并由代理对象控制对目标对象的引用。使用代理对象,是为了在不修改目标对象的基础上,增强目标对象的业务逻辑。

比如目标对象 A,代理对象是 B。

而代理分为静态代理和动态代理,区别是:

静态代理有真实的代理类存在,就是我们会代码中创建一个代理类,并在代理类的方法中调用目标对象的方法,以此来完成代理的工作。动态代理的代理类没有在代码中创建一个代理类,而是在运行时在JVM里面创建代理对象。

2. 什么是静态代理

静态代理是有实实在在的代理类存在,并且和目标类实现相同的接口。

比如,有一个转账业务,现在希望给它增加功能,使在转账之前确认转账人身份,以及转账之后通知收款人。

(1) 接口 AccountServiceDao :

package com.pingguo.spring5.dao;
public interface AccountServiceDao {
    // 主业务逻辑,转账
    void transfer();
}

(2) 接口 AccountServiceDao 的实现类:

package com.pingguo.spring5.dao;
public class AccountServiceImpl implements AccountServiceDao {
    @Override
    public void transfer() {
        System.out.println("调用dao层,完成转账主业务.");
    }
}

(3) 代理类 AccountProxy :

package com.pingguo.spring5.proxy;
import com.pingguo.spring5.dao.AccountServiceDao;
public class AccountProxy implements AccountServiceDao {
    // 目标对象
    private AccountServiceDao target;
    public AccountProxy(AccountServiceDao target) {
        this.target = target;
    }
    
    @Override
    public void transfer() {
        before();
        target.transfer();
        after();
    }
    
    private void before() {
        System.out.println("对转账人身份进行验证.");
    }
    
    private void after() {
        System.out.println("转账完成,已通知收款人.");
    }
}

在代理类中:

(4) 运行测试新建一个测试方法,运行看下结果:

@Test
    public void testProxy() {
        // 创建目标对象
        AccountServiceDao target = new AccountServiceImpl();
        // 创建代理对象
        AccountProxy proxy = new AccountProxy(target);
        proxy.transfer();
    }

结果:

对转账人身份进行验证.
调用dao层,完成转账主业务.
转账完成,已通知收款人.
Process finished with exit code 0

优点:

缺点:

3. 什么是动态代理

与静态代理的硬编码方式相比,动态代理支持运行时动态生成代理对象这种方式。换句话说,动态代理并不存在代理类,代理对象直接由代理生成工具动态生成。

优点:

缺点:

相对于静态代理,它不能增强其中的某一个方法。

对于动态代理,针对于是否存在接口的情况下,又分为 2 种:

使用 JDK 动态代理

使用 JDK 动态代理,创建的是接口实现类的代理对象,以此来实现功能增强。

现在不需要上面创建过的实际代理类了 。

接口,为了后面的一些知识点的说明,里面加个参数,转账的金额:

package com.pingguo.spring5.dao;
public interface AccountServiceDao {
    // 主业务逻辑,转账
    void transfer(int amount);
}

实现类:

package com.pingguo.spring5.dao;
public class AccountServiceImpl implements AccountServiceDao {
    @Override
    public void transfer(int amount) {
        System.out.println("调用dao层,完成转账主业务.金额:" + amount);
    }
}

在测试方法里,直接使用动态代理:

@Test
    public void testDynamicProxy() {
        // 创建目标对象
        AccountServiceDao target = new AccountServiceImpl();
        // 创建代理对象
        AccountServiceDao proxy = (AccountServiceDao) Proxy.newProxyInstance(
                target.getClass().getClassLoader(),  // 目标类使用的类加载器
                target.getClass().getInterfaces(),  // 目标类实现的接口
                new InvocationHandler() {  // 调用处理器
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        System.out.println("对转账人身份进行验证.");
                        Object res =  method.invoke(target, args);
                        System.out.println("转账完成,已通知收款人.");
                        return res;
                    }
                }
        );
        // 让代理工作
        proxy.transfer(10000);
    }

运行结果:

对转账人身份进行验证.
调用dao层,完成转账主业务.金额:10000
转账完成,已通知收款人.
Process finished with exit code 0

动态代理的过程:

对于 invoke 中的 3 个参数,分别是:

使用 CGLIB 动态代理

CGLIB动态代理的原理是生成目标类的子类,这个子类对象就是代理对象,代理对象是被增强过的。

注意,不管有没有接口都可以使用 CGLIB 动态代理, 而不是只有在无接口的情况下才能使用。

示例就暂时不放了,因为我本地环境问题,有个报错始终未解决,后续再说,不影响继续学习 spring。

以上就是Spring AOP底层原理及代理模式的详细内容,更多关于Spring AOP底层原理的资料请关注编程网其它相关文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯