声明:本栏目所使用的素材都是凯哥学堂VIP学员所写,学员有权匿名,对文章有最终解释权;凯哥学堂旨在促进VIP学员互相学习的基础上公开笔记。
代理
什么是代理?代理可以帮我们解决什么问题?
静态代理可以干的事情:
有时候我们有这样一种操作,我们去调用逻辑,但是逻辑方法内,我只写逻辑,不做其他事情。这个数据有效性验证我们不希望与逻辑混在一起。于是我们剥离开来。
当调用逻辑完毕后,我们还要判断逻辑是否正常完毕,如果抛出异常,还需要怎么操作。也就是我们需要在逻辑方法的前后做一些处理善后。
我们要在方法前后做事情。就需要调用逻辑的地方,先不调用逻辑,而是先调用数据有效性验证方法,验证完毕后去调用逻辑。或是调用完毕后再去调用逻辑。
调用逻辑后,在判断方法是否抛出异常,在进行善后操作。
这个操作,我们可以这样:
调用数据验证,调用逻辑。如果抛出异常,怎么处理。如果没有异常怎么处理。
这样就做到了,在方法前后前后做了操作。我们还可以使用静态代理操作。
静态代理做法:
申请接口,申请方法
对接口的实现。这是逻辑方法,我们需要在这个逻辑方法前后执行操作
写类继承与逻辑实现类
当看到这里,已经大概明白什么意思了。先执行操作,再调用父类的逻辑处理,调用处理完后,再执行操作。
很明显,这里就不能直实例化实现类,而是去调用实现类的子类。调用子类的server。
这就是静态代理的类代理,在方法的前后进行了操作。
静态代理的接口代理:
这里不再继承于类,而是实现与接口,重写接口的方法
现在的操作就是这样:实例化继承于接口代理类,在server方法中,完成预处理,拿获得的真正的server处理对象去调用逻辑,在做收尾操作。
静态代理的类代理是这样操作:调用server类的子类,由子类预处理,super调用父类逻辑,调用完毕后再收尾处理。
静态代理的接口代理是这样操作:调用类,由类预处理,获得server对象去调用server,调用完毕后再收尾处理。
类代理与接口代理是一致的,都是不直接调用处理类。由其他类或子类处理完后,在调用具体的处理类
动态代理解决的问题:
代理做到的操作是这样:比如我们要执行方法的日志追踪。我们需要在调用方法前,日志输出,再调用方法,结束前再做日志输出
为什么要方法日志追踪?当出问题时,可以根据日志分析。所以方法日志追踪还是很有必要的。
但是我们的方法上百上千,如果一一给每个方法做日志,那样首先考虑的问题是:这样的操作会不会太重复了。加上成百上千次日志。
这个操作可以由动态代理解决。
动态代理做法:
书写接口
实现接口,重写方法
实现InvocationHandler借口。Invocation翻译:调用。Handler翻译:处理。这是调用处理接口
这里有3个参数,一个proxy:真正的代理对象。Method触发代理时调用的方法,args方法的参数
处理什么调用呢?后面再看,这里还有一步操作是构造器要求对象,有什么用呢?待会再看
获得other接口的实现类的Class。Proxy.newProxyInstance生成动态代理类,需求参数:
实现的classloader实现类的加载器
实现类的接口
处理类
参数我们从class中获得再传入。这样就完成了代理。返回的对象转换为接口。当接口调用方法,会进入拦截器执行。
我们在处理类构造器中,要求参数obj,在这里我们将other对象传进去了。
查看方法invoke。当进入处理类,一律的请求都是发向invoke方法。此方法可以决定是否继续往后调用,像拦截器一样。
如果我们要往后调用,则拿获得的obj对象,method的invoke选择调用obj的这个方法
这个操作是这样的:接口调用方法,并不会进入实现类,而是进入处理类的invoke方法。这个方法可以决定是否继续往后调用。
这个方法上有method方法对象,这个方法对象,是接口调用的那个方法。是那个对象,如果我们要使用method继续往后调用。需要考虑一个问题。
调用method需要考虑的问题,这个method是调用哪个对象的?于是我们将other实现类传递过去,就是为了在这个时候,进行预处理后,method去调用获得的obj对象,就调用到处理类上了。调用完毕后,在做收尾工作。
关于方法的第一个参数与第二个参数,我的猜测是:
有一个实验是这样的:newProxyInstance得到的动态代理类,如果转换为other实现类报错,提示类不匹配,转换出错。如果转接口才会正常运行。
我的想法是:这里生成的动态代理类,是接口的实现类,与接口产生了关系。所以可以转换为接口,而转实现类是不可以的。
所以第二个参数,要求的是interferes,这里就传递了other实现类的接口,我觉得是为了让代理类实现于接口,接口在调用时,就是进入动态代理类。由代理类,转到第三个参数处理类上去。
但是获得代理类转换为接口,再获得的class,从interfaces得到的接口是class对象,但我这里的猜测是他与要代理的类的接口有关系
至于第一个参数类的加载器,没有拿捏的确认想法,但是他获得这个类加载器,应该是为了做一些配置而需要。
当把这三个参数ok后,动态代理就拿下了。第一个给它做参数的配置,第二个用来实现于接口,第三个是明确得到处理类。
届时一旦接口调用方法时,触发进入动态类,动态类转到处理类的invoke方法。如果要真实的调用到业务处理类上,处理类再获得业务处理类的对象,invoke方法上有method对象。如果method.invoke将对象传递,表示调用这个对象的这个method对象方法,则就调用到了业务实际处理类,在方法前后完成了预处理与善后操作。
这里动态代理的好处在那里呢?动态代理类不需要我们写,生成即可,进入处理类进行代理操作。
动态代理类的好处在于,代理类不需要我们写。我们直接在处理类中操作
我们于是就可以这样干,将处理类分出去,给其余要产生代理类的使用。这样他们产生代理类后,就会进入我们的处理类。
动态代理类与静态代理的区别这里:静态代理类需要自己写,不论是接口代理还是类代理。而动态代理是自己生成,届时我们只需要在处理类中操作即可。
如果我们要动态代理一个类,那么我们每次都需要newProxyInstance生成。每代理一个类都需要产生一个代理类。但处理类可以只写一份实例化多份分出去使用。但也可以写有多个。
这就是动态代理,其过程,并不会真正调用到处理类,是调用接口的方法时,会进入代理类,在转到处理类。要调用真正的处理类,还需要我们手动操作。在我们调用前后,可以由我们操作。动态代理,类不需要我们生成,调用接口进入代理类转到处理类,我们只需要关系一个处理类的操作即可。
代理又称切面,为什么叫切面?是这样的,我们本来的处理是执行的好好的,但我们要在执行的操作前与后执行操作。这就像切下去一样,本来的操作,横切一刀进行操作。所以叫切面。这是我的解释,很多名词都是与日常有联系的。
为什么不论是静态代理,还是动态代理,都是以接口来操作。都是面向接口来操作的。我们可以这样写的:
ServerIF ser=new xxx(); //接口
Server ser=new xxx(); //实现类
使用接口的目的也很好理解,接口可以不变,但类是需要变的,接口的变,无非是增加代码,类的类就可能会影响其余的地方。但是使用接口,其余地方使用调用,更换了接口的实现类,其余地方正常使用。但如果使用的是类,对类改变,比如更换类,更换子类,那么其余对类的地方也需要修改。这个时候就只能改源码了。而接口增加也是增加功能呢,不会影响其他地方调用。增加个子类,返回子类,无需改源码,功能就扩展。这就是我觉得的解耦与开闭原则的意思
这就是代理:
静态类代理:接口的内存地址是逻辑类的子类,接口调用方法,转到子类,子类处理转父类
静态接口代理:接口的内存地址是接口的实现类,接口调用转到实现类,实现类拿逻辑类的对象调用逻辑类
两种代理,都是不调用逻辑类,转发过去调用。只是两种方式不同。
动态代理:代理类不需要我们写,我们只需要关系处理类。
猜测:代理类实现于接口,接口调用时,转到代理类,处理类再转到处理类。我们在处理类中操作。处理类如果要调用逻辑类,需要处理类获得逻辑类对象,去调用。
动态代理类,有点像静态代理的接口代理,负责帮我们拦截,但真正要操作过去,还需要获得逻辑类对象去操作
这就是代理,在方法的前与后可以进行操作。这种横切一刀插入的操作,又称切面编程。
相关推荐
首先,JavaSE(Java标准版)是所有Java学习的基础,它涵盖了Java语言的核心概念。从Java基础开始,包括环境变量配置、面向对象编程、数据类型、运算符、字符串操作、输入输出、控制流程、数组、Date类、final和...
面向对象的三大特性——封装、继承和多态,在06面向对象(上)、07面向对象(中)和08面向对象(下)中进行了详细介绍。其中,封装是保护数据免受外部世界干扰,继承允许子类继承父类的属性和方法,而多态则提供了...
以下是基于描述中提到的两个文件——"Java基础每日复习笔记-JavaSE基础阶段.edf"和"Java基础每日复习笔记-JavaSE高级阶段.edf"——所包含的知识点的详细阐述: 1. **Java SE基础阶段**: - **Java简介**:了解Java...
1. **反射**:深入讲解Java反射机制,如何动态获取和修改类的信息,以及动态代理的实现。 2. **注解(Annotation)**:介绍注解的使用,元注解,自定义注解以及如何通过反射处理注解。 3. **Java集合高级主题**:...
### 开发入门:前端开发资料参考 —— Android 入门篇 #### 一、环境配置 随着移动互联网的快速发展,前端开发的概念早已超越了传统的网页端范畴,Android系统的普及更是为前端开发工程师提供了新的机遇与挑战。...
- 反射:反射是Java强大的特性,允许在运行时检查类的信息并动态调用方法,面试中可能要求实现基于反射的动态代理或操作私有属性。 - JVM:理解JVM内存模型,垃圾收集机制,性能优化策略等,对于解决性能问题至关...
习题可能包括基本语法,如变量声明、数据类型、控制结构(if语句、switch语句、循环)、函数的使用和定义,以及面向对象编程的基础——类与对象的创建和使用。这些问题将帮助学习者巩固对这些核心概念的理解。 面向...
**Spring Cloud** 是一套构建在 **Spring Boot** 基础之上的微服务开发框架,旨在简化分布式系统中常见的模式(例如配置管理、服务发现、断路器、智能路由、微代理、控制总线等)的实现过程。通过 Spring Cloud,...
#### 一、环境搭建基础——IDE选择与配置 ##### 1.1 IDE选择:Eclipse 对于Android开发来说,选择合适的集成开发环境(IDE)至关重要。根据给定的内容,这里推荐使用Eclipse作为Android开发工具。Eclipse是一款...
### 接口测试工具——JMeter #### 四、JMeter简介 Apache JMeter是一款开源的压力测试工具,主要用于性能测试和功能测试,特别是在接口测试方面表现优异。 #### 五、JMeter环境搭建步骤 1. **安装JDK**: - 访问...
Java的三大版本——JavaSE、JavaEE和JavaME分别面向桌面应用、企业级应用和嵌入式设备。Java社区和生态系统非常活跃,不断更新和改进,使得Java成为持续发展的强大开发语言。理解并熟练掌握这些基础知识,对于成为一...
### 网格安装(Globus Toolkit 4)——详细步骤与配置 #### 一、安装环境 在本文档中,我们将详细介绍如何在Fedora Core 4操作系统上安装和配置Globus Toolkit 4.0.5(简称GT4)。为了实现网格计算的功能,我们将在...