javase——代理

     2022-04-16     158

关键词:

声明:本栏目所使用的素材都是凯哥学堂VIP学员所写,学员有权匿名,对文章有最终解释权;凯哥学堂旨在促进VIP学员互相学习的基础上公开笔记。

代理

什么是代理?代理可以帮我们解决什么问题?

静态代理可以干的事情:

有时候我们有这样一种操作,我们去调用逻辑,但是逻辑方法内,我只写逻辑,不做其他事情。这个数据有效性验证我们不希望与逻辑混在一起。于是我们剥离开来。

当调用逻辑完毕后,我们还要判断逻辑是否正常完毕,如果抛出异常,还需要怎么操作。也就是我们需要在逻辑方法的前后做一些处理善后。

我们要在方法前后做事情。就需要调用逻辑的地方,先不调用逻辑,而是先调用数据有效性验证方法,验证完毕后去调用逻辑。或是调用完毕后再去调用逻辑。

调用逻辑后,在判断方法是否抛出异常,在进行善后操作。

这个操作,我们可以这样:

image

调用数据验证,调用逻辑。如果抛出异常,怎么处理。如果没有异常怎么处理。

这样就做到了,在方法前后前后做了操作。我们还可以使用静态代理操作。

静态代理做法:

image

申请接口,申请方法

image

对接口的实现。这是逻辑方法,我们需要在这个逻辑方法前后执行操作

image

写类继承与逻辑实现类

当看到这里,已经大概明白什么意思了。先执行操作,再调用父类的逻辑处理,调用处理完后,再执行操作。

image

很明显,这里就不能直实例化实现类,而是去调用实现类的子类。调用子类的server。

这就是静态代理的类代理,在方法的前后进行了操作。

静态代理的接口代理:

image

这里不再继承于类,而是实现与接口,重写接口的方法

image

现在的操作就是这样:实例化继承于接口代理类,在server方法中,完成预处理,拿获得的真正的server处理对象去调用逻辑,在做收尾操作。

静态代理的类代理是这样操作:调用server类的子类,由子类预处理,super调用父类逻辑,调用完毕后再收尾处理。

静态代理的接口代理是这样操作:调用类,由类预处理,获得server对象去调用server,调用完毕后再收尾处理。

类代理与接口代理是一致的,都是不直接调用处理类。由其他类或子类处理完后,在调用具体的处理类

动态代理解决的问题:

代理做到的操作是这样:比如我们要执行方法的日志追踪。我们需要在调用方法前,日志输出,再调用方法,结束前再做日志输出

为什么要方法日志追踪?当出问题时,可以根据日志分析。所以方法日志追踪还是很有必要的。

但是我们的方法上百上千,如果一一给每个方法做日志,那样首先考虑的问题是:这样的操作会不会太重复了。加上成百上千次日志。

这个操作可以由动态代理解决。

动态代理做法:

image

书写接口

image

实现接口,重写方法

image

实现InvocationHandler借口。Invocation翻译:调用。Handler翻译:处理。这是调用处理接口

这里有3个参数,一个proxy:真正的代理对象。Method触发代理时调用的方法,args方法的参数

处理什么调用呢?后面再看,这里还有一步操作是构造器要求对象,有什么用呢?待会再看

image

获得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(); //实现类

使用接口的目的也很好理解,接口可以不变,但类是需要变的,接口的变,无非是增加代码,类的类就可能会影响其余的地方。但是使用接口,其余地方使用调用,更换了接口的实现类,其余地方正常使用。但如果使用的是类,对类改变,比如更换类,更换子类,那么其余对类的地方也需要修改。这个时候就只能改源码了。而接口增加也是增加功能呢,不会影响其他地方调用。增加个子类,返回子类,无需改源码,功能就扩展。这就是我觉得的解耦与开闭原则的意思

这就是代理:

静态类代理:接口的内存地址是逻辑类的子类,接口调用方法,转到子类,子类处理转父类

静态接口代理:接口的内存地址是接口的实现类,接口调用转到实现类,实现类拿逻辑类的对象调用逻辑类

两种代理,都是不调用逻辑类,转发过去调用。只是两种方式不同。

动态代理:代理类不需要我们写,我们只需要关系处理类。

猜测:代理类实现于接口,接口调用时,转到代理类,处理类再转到处理类。我们在处理类中操作。处理类如果要调用逻辑类,需要处理类获得逻辑类对象,去调用。

动态代理类,有点像静态代理的接口代理,负责帮我们拦截,但真正要操作过去,还需要获得逻辑类对象去操作

这就是代理,在方法的前与后可以进行操作。这种横切一刀插入的操作,又称切面编程。

##(⊙o⊙)值得收藏的javase万字进阶版(⊙o⊙)##javase高级反射-动态代理-设计模式-jvm篇(代码片段)

...ava中的反射1-1.说说你对Java中反射的理解二、Java中的动态代理2-1写一个ArrayList的动态代理类2-2动静态代理的区别,什么场景使用?三、Java中的设计模式&回收机制3-1.你所知道的设计模式有哪些?3-2单例设计模式3-3... 查看详情

javase8基础proxy对接口进行动态代理简单示例

礼悟:          好好学习多思考,尊师重道存感恩。叶见寻根三返一,活水清源藏于零。          虚怀若谷良心主,皓月当空自在王。愿给最苦行无悔,诚... 查看详情

javase-day15

...类,并支持多继承 implements interface   代理模式Proxy  &nb 查看详情

java反射机制动态代理初探

动态代理是javase中重要的一环,比如说spring框架的aop基本上都是用动态代理实现的。动态代理也能帮助程序员减少工作量,减少代码的冗余。但是java本身的动态代理必须是实现了接口的类才能运用代理,这是一个缺点。接口:&n... 查看详情

java探针技术-jvm的动态agent机制:在main函数启动之后运行agent

  premain是JavaSE5开始就提供的代理方式,由于其必须在命令行指定代理jar,并且代理类必须在main方法前启动。因此,要求开发者在应用前就必须确认代理的处理逻辑和参数内容等等。在有些场合下,premain代理方式不能满足需... 查看详情

将jms消息从javaee应用程序发送到javase应用程序

...人和相同的主题。所以我有一个外部Artemis实例作为消息代理运行,并在JavaEE应用程序的单独bean中成功设置了生产者和使用者。他们都 查看详情

通过代理使用 netty 3.4.2.Final

】通过代理使用netty3.4.2.Final【英文标题】:Workingviaproxywithnetty3.4.2.Final【发布时间】:2013-03-0711:14:20【问题描述】:是否可以使用此处描述的Netty:http://docs.oracle.com/javase/6/docs/technotes/guides/net/proxies.html也许有一些选项,例如:Sys... 查看详情

javase主要内容

JavaSE的主要学习内容--java基础(重点)1.java语法2.面向对象3.javaAPIJavaSE是Java平台标准版的简称(JavaPlatform,StandardEdition)(alsoknownasJava2Platform),用于开发和部署桌面、服务器以及嵌入设备和实时环境中的Java应用程序。JavaSE包括用于开... 查看详情

javase知识树

查看详情

javase-内存分析

    查看详情

javase路径问题

importjava.io.File;importjava.io.FileInputStream;importjava.io.IOException;importjava.io.InputStream;/***路径问题javase*@authorviakiba*/publicclassIo{publicstaticvoidmain(String[]args)throwsException{/*// 查看详情

javase_流程控制

顺序结构没有特定语法结构,按照代码先后顺序,依次执行。 查看详情

javase的安装

一、JAVA分类JAVAEE——JAVA企业版,主要用于WEB开发。JAVASE——JAVA标准版,主要用于应用程序开发。JAVAME——JAVA移动版,主要用于移动应用开发。二、JAVASE的安装JAVA的运行需要JAVA虚拟机(JVM),这是它实现跨平台的根本。JAVA的... 查看详情

javase13新增特性

JavaSE13新增特性作者:Grey原文地址:JavaSE13新增特性源码源仓库:Github:java_new_features镜像仓库:GitCode:java_new_features新版Switch使用方式switch语句增加了yield关键字表示返回本文来自博客园,作者:GreyZeng,转载请注明原文链接:https... 查看详情

javase笔记

...知识点:OOP、封装、继承、多态、接口、第三部分:开发JavaSE高级应用程序主要知识点:异常、集合、|℃、多线程、反射机 查看详情

charles安装和free

一、准备工作简介Charles是一款代理服务器,通过将自己设置成系统(电脑或者浏览器)的网络访问代理服务器,然后截取请求和请求结果进行分析抓包。该软件是用Java写的,能够在Windows,Mac,Linux上使用。安装Charles的时候要先... 查看详情

javase,ee,me区别

JavaSE(JavaPlatform,StandardEdition):java平台标准版;JavaEE(JavaPlatform.EnterpriseEdition):java平台企业版;JavaME(JavaPlatform,MicroEdition):java平台微型版;  查看详情

【jvm&proxy】为jvm配置代理

...###########################################注:1.10.10.10.108080为示例代理的IP和PORT2.http.nonProxyHosts,注意中间是non,不是no3.http.nonProxyHosts如果有多个,用英文符号|分割HowdoIsettheproxytobeusedbytheJVM?https://stackoverflow.com/questions/120797/how-do-i-set-the... 查看详情