我的编程空间,编程开发者的网络收藏夹
学习永远不晚

SpringAOP的底层实现方式-代理模式

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

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

SpringAOP的底层实现方式-代理模式

在学习Spring的过程中,留下一下痕迹。

代理模式,其实就是让别人做同样的事情,但是别人却不仅将我的事情做了,还会把他的事情也做了,换言之,这个人做的事情,是他独有的事情和我需要做的事情的综合。回到代码,那么就是,代理类执行与委托类同样的方法,在这方法里代理类不仅可以执行委托类的方法的内容,还可以添加自己的另外的内容,在使用代理类的时候,会比直接使用委托类具有更多的能力,所以我们会直接使用代理类。

通常,代理类虽然具备更多的能力,但是代理类更多的能力其实是比较固定的。

例如,在JDBC里,或在ORM框架里,都会存在事务的开启和提交,如果我们直接将事务代码和业务代码写在一起,其实也是可以的,不过,这样做会使得每一个需要事务的方法,都要添加事务代码,造成代码的分散冗余,那么,针对这种情况,我们希望业务代码可以抽离出来,每一个业务方法都只写业务内容,同时我们又希望,在执行业务方法时,可以有一种方式自动添加业务代码,这种需求,其实就是有了代理的需求,因为我们希望还是使用原来的方法,但是出来的效果希望是多出事务代码,也就是希望业务代码得到增强。可以这样理解了,抽离出来的业务代码,是一个委托类,而可以将委托类自动增强并添加事务代码的代码,是一个代理类,它代理执行委托类,具备了委托类原有的业务能力之余,增加了事务处理的代码。

我理解的代理模式,其实就是将委托类融入到代理类里,换句话说,代理类也就是委托类的扩充而已。

还有不仅是spring 的AOP是代理模式,还有Struts2的拦截器实现也是基于动态代理的,动态代理是一种很常见也很重要的设计模式。

说了很多,那么如何实现代理,那我们先说说静态代理。

1.1 静态代理

一个接口,两个实现类,代理实现类组合真实实现类

静态代理,是一种根据上面的理论,很自然会想到的一种不依赖于其他技术的代理模式实现方式。而他的实现过程如下图。

这里写图片描述

如果使用过静态代理,那么很容易理解,静态代理存在的缺陷。

因此,也就出现了动态代理。

动态代理的动态, 就是可以动态的切换真实实现类, 也就是说可以一个代理类(相同的代码, 相同的增强操作)应对一堆不确定的真实实现类.

1.2 动态代理

JDK动态代理和CGlib字节码动态代理

1.2.1 JDK动态代理(必须有接口)

通过java.lang.reflect.Proxy类实现。

动态代理就是为了解决静态代理不灵活的缺陷而产生的。静态代理是固定的,一旦确定了代码,如果委托类新增一个方法,而这个方法又需要增强,那么就必须在代理类里重写一个带增强的方法。而动态代理可以灵活替换代理方法,动态就是体现在这里

这里写图片描述


public interface TargetClass {
    void sayHello();
}

public class TargetClassImpl implements TargetClass{
    public void sayHello() {
        System.out.println("你好");
    }
}

public class JdkProxy implements InvocationHandler {
    private TargetClass targetClass;
    public Object createProxy(TargetClass targetClass){
        //传入真实实现类, 本身要做的事情会由他自己做, 代理类会额外进行其他增强操作
        this.targetClass = targetClass; 
        //获取本类类加载器
        ClassLoader classLoader = JdkProxy.class.getClassLoader();
        ///获取被代理对象的所有接口
        Class[] clazz = targetClass.getClass().getInterfaces();
        System.out.println(clazz.length);
        //生成代理类并返回
        return Proxy.newProxyInstance(classLoader, clazz, this);
    }
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("JDKProxy前置增强");
        Object obj = method.invoke(targetClass,args);
        System.out.println("JDKProxy后置增强");
        return obj;
    }
}

public class Test {
    public static void main(String[] args) {
		JdkProxy jdkProxy = new JdkProxy();
		TargetClass targetClass = new TargetClassImpl();
		TargetClass targetClass1 = (TargetClass) jdkProxy.createProxy(targetClass);
		targetClass1.sayHello();
}

1.2.2 CGlib动态代理

(不需要类继承任何接口,字节码技术)

CGlib包在Spring core包里。

这里写图片描述


public class CGlibTaretClass {
    public void sayHello(){
        System.out.println("我是CGlib,我不需要接口");
    }
}

package CGlibProxyTest;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class CGlibProxy implements MethodInterceptor{
    //代理方法
    public Object createProxy(Object target){
        //创建一个动态类对象
        Enhancer enhancer = new Enhancer();
        //确定要增强的类,设置期父类
        enhancer.setSuperclass(target.getClass());
        //添加回调函数
        enhancer.setCallback(this);
        //返回创建的代理类
        return enhancer.create();
    }
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("CGlib前置增强");
        Object obj = methodProxy.invokeSuper(o,objects);
        System.out.println("CGlib后置增强");
        return obj;
    }
}

public class Test {
    public static void main(String[] args) {
		CGlibProxy cGlibProxy = new CGlibProxy();
        CGlibTaretClass cGlibTaretClass = new CGlibTaretClass();
        CGlibTaretClass cGlibTaretClass1 = (CGlibTaretClass)cGlibProxy.createProxy(cGlibTaretClass);
        cGlibTaretClass1.sayHello();
   }

最后:代理模式解决的是常见的代码组织问题,它并不神秘,不要被他的名字吓倒。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

免责声明:

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

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

SpringAOP的底层实现方式-代理模式

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

SpringAop实现原理及代理模式是什么

这篇文章主要介绍了SpringAop实现原理及代理模式是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇SpringAop实现原理及代理模式是什么文章都会有所收获,下面我们一起来看看吧。Spring Aop的
2023-06-29

Spring AOP底层机制之代理模式

如何实现在不修改源码的基础上实现代码功能的增强呢?spring为我们提供了代理模式。所谓的代理模式通俗来说就是一个中介,它给某一个对象提供一个代理对象,并由代理对象控制原对象的引用,从而实现在不修改源码的基础上实现代码功能的增强
2022-11-13

Spring AOP底层原理及代理模式实例分析

这篇文章主要介绍“Spring AOP底层原理及代理模式实例分析”,在日常操作中,相信很多人在Spring AOP底层原理及代理模式实例分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Spring AOP底
2023-06-30

python 实现 代理模式

本文的目录地址本文的代码地址在某些应用中,我们需要在访问某个对象之前执行一个或多个重要的操作,例如,访问敏感信息——在允许用户访问敏感信息之前,我们希望确保用户具备足够的权限。操作系统也存在类似的情况,用户必须具有管理员权限才能在系统中安装
2023-01-31

Java设计模式的代理模式怎么实现

这篇文章主要介绍了Java设计模式的代理模式怎么实现的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Java设计模式的代理模式怎么实现文章都会有所收获,下面我们一起来看看吧。什么是代理模式代理模式的定义: 由于某
2023-06-30

JavaScript 代理模式的深层解析:从理论到实践

JavaScript 代理模式是一种强大的设计模式,允许您在现有对象的基础上创建其加强或扩展版本。本文深入探讨代理模式的原理、类型,并通过代码示例展示其应用。
JavaScript 代理模式的深层解析:从理论到实践
2024-03-09

如何实现PHP底层的分布式计算

如何实现PHP底层的分布式计算随着互联网的快速发展,分布式计算变得越来越重要。而对于PHP开发者来说,实现PHP底层的分布式计算是一个有挑战性的任务。本文将介绍如何使用PHP进行分布式计算,并提供一些具体的代码示例。分布式计算是将一个复杂的
如何实现PHP底层的分布式计算
2023-11-08

如何实现PHP底层的分布式缓存

如何实现PHP底层的分布式缓存随着互联网和大数据时代的到来,对于系统的性能和响应时间要求越来越高。分布式缓存作为提高系统性能的一种重要方式,被广泛应用于各种Web应用中。本文将介绍如何使用PHP底层来实现分布式缓存,并提供具体的代码示例。一
如何实现PHP底层的分布式缓存
2023-11-08

Java代理模式怎么实现

这篇文章主要讲解了“Java代理模式怎么实现”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java代理模式怎么实现”吧!结构型模式前面创建型模式介绍了创建对象的一些设计模式,这节介绍的结构型
2023-06-02

Java代理模式如何实现

这篇文章主要介绍“Java代理模式如何实现”,在日常操作中,相信很多人在Java代理模式如何实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java代理模式如何实现”的疑惑有所帮助!接下来,请跟着小编一起来
2023-06-19

Go代理模式怎么实现

Go语言中实现代理模式可以使用结构体和接口的方式。首先,定义一个接口,代理和被代理对象都必须实现这个接口。这里以一个简单的计算器为例:```gotype Calculator interface {Add(a, b int) intSubt
2023-08-08

java如何实现代理模式

小编给大家分享一下java如何实现代理模式,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!定义:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象
2023-05-30

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录