Spring AOP底层原理及代理模式

目录
  • Spring AOP底层原理代理模式
    • 一、什么是 AOP
    • 二、AOP 底层原理
      • 1. 什么是代理?
      • 2. 什么是静态代理
      • 3. 什么是动态代理

Spring AOP底层原理代理模式

一、什么是 AOP

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

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

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

二、AOP 底层原理

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

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

1. 什么是代理?

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

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

  • 那么现在 B 对 A 进行引用,可以实现 A 有的功能。
  • 另外,B 还可以在自身进行一些新功能,最终不需要修改目标对象 A 。

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

静态代理有真实的代理类存在,就是我们会代码中创建一个代理类,并在代理类的方法中调用目标对象的方法,以此来完成代理的工作。动态代理的代理类没有在代码中创建一个代理类,而是在运行时在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("转账完成,已通知收款人.");
    }
}

在代理类中:

  • 添加了添加了目标对象,并且有参构造方法里需要传入目标对象。
  • 代理方法里,调用了目标对象里的转账方法 target.transfer()。
  • before() 和 after() 则是 2个增强的方法,分别作用于 target.transfer() 的前面和后面。

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

@Test
    public void testProxy() {
        // 创建目标对象
        AccountServiceDao target = new AccountServiceImpl();
        // 创建代理对象
        AccountProxy proxy = new AccountProxy(target);
        proxy.transfer();
    }
  • 这里先创建了目标对象
  • 再创建代理对象,并且把目标对象传入
  • 最后调用代理对象里的,被增强过的方法 transfer()。

结果:

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

优点:

  • 效率高,因为所有的类都是已经编写完成的,使用的时候只需要取得代理对象并且执行即可。
  • 同时也可以实现对目标对象中指定的方法进行增强。

缺点:

  • 与目标类实现相同的接口代码,冗余。
  • 如果接口发生改变,代理类中的方法也要修改。
  • 代理类服务于一种类型的对象,如果要服务多类型的对象,那么要为每种类型的对象都生成代理类。

3. 什么是动态代理

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

优点:

  • 用很少的代码对一个类的所有方法实现一样的增强效果。
  • 在编码时,代理逻辑与业务逻辑互相独立,各不影响,减少侵入,降低耦合。

缺点:

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

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

  • 有接口的情况下,使用 JDK 动态代理。
  • 无接口的情况下,使用 CGLIB 动态代理。

使用 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

动态代理的过程:

  • 创建处理器 InvocationHandler实例。
  • 在调用目标对象时,会调用代理对象。
  • 代理对象去请求目标对象。invoke 方法就是调用目标对象的方法生成代理对象的过程。
  • 同时,在 invoke 方法中进行功能增强。

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

  • Object proxy:代理对象,一般不会使用。
  • Method method:外面的代理对象调用的方法引用,这里引用的就是 transfer()
  • Object[] args:外面的代理对象调用的方法里面的参数,这里就是参数 amount。

使用 CGLIB 动态代理

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

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

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

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

(0)

相关推荐

  • 深入解析spring AOP原理及源码

    目录 @EnableAspectJAutoProxy 找切面 代理对象的创建 代理方法的执行 ExposeInvocationInterceptor#invoke 环绕通知的执行 前置通知的执行 后置通知的执行 返回后通知的执行 异常通知的执行 @EnableAspectJAutoProxy @EnableAspectJAutoProxy注解用于开启AOP功能,那么这个注解底层到底做了什么呢? 查看@EnableAspectJAutoProxy的源码,发现它使用@Import注解向Spring容

  • Spring AOP操作的相关术语及环境准备

    目录 一.常用术语 二.准备工作 1. 引入依赖 2. 切入点表达式 (1)示例1 (2)示例2 一.常用术语 在后续使用 AOP 中会用到几个专业术语:连接点.切入点.通知(增强).切面. 分别是什么意思? 来看这里有个 User 类,里面有增删改查 4 个方法. public class User { public void add() {} public void delete() {} public void update() {} public void select() {} } 以

  • Java的Spring AOP详细讲解

    目录 什么是AOP&作用 AOP的动态代理技术 基于JDK的动态代理 cglib动态代理 AOP相关概念 AOP开发明确事项 需要编写的内容 AOP技术实现的内容 AOP底层使用哪种代理方式 基于XML的AOP开发 切面表达式 通知类型 切点表达式抽取 基于注解的AOP开发 注解通知类型和切面表达式的抽取 类型 抽取表达式 总结 什么是AOP&作用 AOP 为 Aspect Oriented Programming 的缩写,意思为面向切面编程,是通过预编译方式和运行期动态代理实现程序功能的

  • Spring学习通过AspectJ注解方式实现AOP操作

    目录 Spring注解AspectJ操作AOP 一.被增强类 二.增强类 三.进行通知的配置 1. spring 配置文件中,开启扫描. 2. 使用注解创建 User 和 UserProxy 对象 3. 在增强类上使用注解 @Aspect 4. spring配置,开启生成代理对象 5. 配置不同类型的通知 四.抽取相同切入点 五.多个增强类的优先级 Spring注解AspectJ操作AOP 一.被增强类 新建一个被增强的类 User,下面有个 add() 方法. package com.ping

  • Spring AOP 创建代理对象详情

    目录 1 前言 2 创建代理对象 3 AOPContext Aop 上下文 4 AOP 分析汇总 5 JDK 动态代理和 CGLIB 的区别与联系 6 总结 1 前言 在这篇文章中中已经讲述了 AOP 的后置处理器和增强信息的获取,在本文中将继续分享 AOP 创建代理对象和上下文相关的内容. 2 创建代理对象 Spring AOP 使用 JDKProxy 和 CGLIB 两种方式来生成代理对象,具体使用哪一种需要根据 AopProxyFactory 接口的 createProxy 方法中的 Ad

  • 详解Java Spring AOP

    目录 前言 一.AOP底层原理 1.AOP底层使用动态代理 二.AOP术语 1.连接点 2.切入点 3.通知(增强) 4.切面 三.AOP 操作(准备工作) Spring 框架一般都是基于 AspectJ 实现 AOP 操作 方式一:使用Spring的接口实现增添功能 方式二:自定义类 方式三:全注解配置实现 总结 前言 面向切面编程,利用 AOP 可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率.即不改变源代码而添加新功能,可插

  • Spring AOP底层原理及代理模式

    目录 Spring AOP底层原理代理模式 一.什么是 AOP 二.AOP 底层原理 1. 什么是代理? 2. 什么是静态代理 3. 什么是动态代理 Spring AOP底层原理代理模式 一.什么是 AOP AOP 就是面向切面编程,是 OOP(面向对象编程)的延续. 利用 AOP 可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序可用性,同时也提高了开发效率. 通俗一点说,不用修改原代码,可以给原代码增加新的功能. 二.AOP 底层原理 AOP 底层原理是使用动

  • Spring AOP底层机制之代理模式

    目录 代理模式 静态代理 静态代理再理解 动态代理 深化理解 动态代理的好处 代理模式 为什么要学习代理模式,因为AOP的底层机制就是动态代理! 代理模式: 静态代理 动态代理 学习aop之前 , 我们要先了解一下代理模式! 静态代理 静态代理角色分析 抽象角色 : 一般使用接口或者抽象类来实现 真实角色 : 被代理的角色 代理角色 : 代理真实角色 ; 代理真实角色后 , 一般会做一些附属的操作 . 客户 : 使用代理角色来进行一些操作 . 代码实现 Rent . java 即抽象角色 pub

  • spring aop底层原理及如何实现

    前言 相信每天工作都要用spring框架的大家一定使用过spring aop,aop的概念是面向切面编程,相对与传统的面向对象编程oop,aop更关注的是横向的逻辑,比如说一个大型系统中的日志记录,异常处理,性能监控等等,都是各个模块都需要的操作,那样代表着这些操作会散落在系统的各个地方,不易管理且杂乱无章,而aop就是关注的这些,aop将这些操作与业务代码分离,统一成一个个的切面,针对这些个切面进行编程处理.spring aop使得我们的aop开发工作变得简单,这次我就给大家讲讲spring

  • SpringAop实现原理及代理模式详解

    目录 Spring Aop的原理 1. JDK动态代理 2. CGLIB动态代理 3. Spring项目中如何强制使用CGLIB代理方式 Spring Aop的原理 Spring的AOP就是通过动态代理实现的.当为某个Bean或者某些Bean配置切面时,Spring会为其创建代理对象,当调用该对象的某个方法时,实际是调用生成的代理类的对象方法.Spring的Aop主要是使用了两个动态代理,分别是JDK的动态代理和CGLIB动态代理. 1. JDK动态代理 如果代理类实现了接口,Spring默认会

  • Spring AOP底层源码详解

    ProxyFactory的工作原理 ProxyFactory是一个代理对象生产工厂,在生成代理对象之前需要对代理工厂进行配置.ProxyFactory在生成代理对象之前需要决定到底是使用JDK动态代理还是CGLIB技术. // config就是ProxyFactory对象 // optimize为true,或proxyTargetClass为true,或用户没有给ProxyFactory对象添加interface if (config.isOptimize() || config.isProxy

  • Spring Boot 底层原理基础深度解析

    目录 1. 底层注解@Configuration 2. 底层注解@Import 3. 底层注解@Conditional 1. 底层注解@Configuration @Configuration 注解主要用于给容器添加组件(Bean),下面实践其用法: 项目基本结构: 两个Bean组件: User.java package com.menergy.boot.bean; /** * 用户 */ public class User { private String name; private Inte

  • Spring AOP里的静态代理和动态代理用法详解

    什么是代理? 为某一个对象创建一个代理对象,程序不直接用原本的对象,而是由创建的代理对象来控制原对象,通过代理类这中间一层,能有效控制对委托类对象的直接访问,也可以很好地隐藏和保护委托类对象,同时也为实施不同控制策略预留了空间 什么是静态代理? 由程序创建或特定工具自动生成源代码,在程序运行前,代理类的.class文件就已经存在 通过将目标类与代理类实现同一个接口,让代理类持有真实类对象,然后在代理类方法中调用真实类方法,在调用真实类方法的前后添加我们所需要的功能扩展代码来达到增强的目的. 优点

  • Spring AOP的底层实现方式-代理模式

    目录 1.1 静态代理 1.2 动态代理 1.2.1 JDK动态代理(必须有接口) 1.2.2 CGlib动态代理 在学习Spring的过程中,留下一下痕迹. 代理模式,其实就是让别人做同样的事情,但是别人却不仅将我的事情做了,还会把他的事情也做了,换言之,这个人做的事情,是他独有的事情和我需要做的事情的综合.回到代码,那么就是,代理类执行与委托类同样的方法,在这方法里代理类不仅可以执行委托类的方法的内容,还可以添加自己的另外的内容,在使用代理类的时候,会比直接使用委托类具有更多的能力,所以我们

  • Spring AOP实现原理解析

    什么是AOP AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善.OOP引入封装.继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合.当我们需要为分散的对象引入公共行为的时候,OOP则显得无能为力.也就是说,OOP允许你定义从上到下的关系,但并不适合定义从左到右的关系.例如日志功能.日志代码往往水平地散布在所有对象层次中,而与它所散布到的对象的核心功能毫无

  • spring源码阅读--aop实现原理讲解

    目录 aop实现原理简介 代理实现的处理器(BeanPostProcessor) 代理实现的源头–AnnotationAwareAspectJAutoProxyCreator AnnotationAwareAspectJAutoProxyCreator的继承结构 代理对象(Proxy)的创建 解析并缓存切面 适配切面 aop实现原理简介 首先我们都知道aop的基本原理就是动态代理思想,在设计模式之代理模式中有介绍过这两种动态代理的使用与基本原理,再次不再叙述. 这里分析的是,在spring中是如

随机推荐