使用djcproxy创建代理对象

在过去的几周中,我展示了如何使用Java Reflection API和cglib创建代理对象。 在本文中,我将向您展示如何使用djcproxy做到这一点。

哦,不是,另一个代理实现!

除了我创建此代理的自私事实之外,还要写些什么呢? 关键是这是一个用Java编写的代理,它创建了可以检查的Java代码。 它还可以即时编译和加载创建的Java类,因此它也可以使用,但主要优点是您可以轻松了解动态代理的工作原理。 至少比深入研究cglib的代码要容易得多,后者直接创建字节码。

如何使用它

您可以从github获取源代码,也可以将依赖项添加到项目maven pom中。

<dependency><groupId>com.javax0</groupId><artifactId>djcproxy</artifactId><version>2.0.3</version>
</dependency>

之后,您可以使用以下代码:

class A {public int method() {return 1;}
}
class Interceptor implements MethodInterceptor {@Overridepublic Object intercept(Object obj, Method method, Object[] args,MethodProxy mproxy) throws Exception {if (method.getName().equals("toString")) {return "interceptedToString";}return 0;}
}...A a = new A();ProxyFactory<A> factory = new ProxyFactory<>();A s = factory.create(a, new Interceptor());

可以在GitHub中的项目测试中找到此代码。 这是一个易于编辑的易于编辑的缩写版本。

类“ A”是原始类,当我们要创建新的代理对象时,我们将创建一个已存在对象的代理。 这不同于反射或屈服。 如果使用cgilib,您将创建一个代理对象,它“包含”原始对象。 从OO术语来看,它并不是真正的包含,因为代理类扩展了原始类。 但是,由于此扩展,代理对象也是原始类的实例。 Cgilib并不真正在乎您要拦截哪个类实例(对象)。 如果需要,可以将对任何对象实例的引用注入到拦截器中。 Djcproxy使用了一种不同的方法,它可以为您做到这一点,在拦截器中,您将获得此对象作为参数传递。 这就是为什么您必须在第20行实例化该对象的原因。

Interceptor实现了库中也提供的接口MethodInterceptor 。 它只有一种方法: intercept ,在调用代理对象方法时调用。 参数是

  • obj –原始对象
  • method –在代理对象中调用的方法
  • args –传递给代理对象上的方法调用的参数。 注意原始参数将被装箱。
  • mproxy –方法代理,可用于在原始对象上或仅在相同类型的任何其他对象上调用方法

这就是关于如何使用该库的全部内容。 接下来的事情是查看生成的内容,以便您可以更好地了解代理的工作方式。 即使您使用其他代理,洞察力也不会伤害您。 当您了解所使用的库的原理时,很多时候调试或仅生成更好的代码会更容易。

尽管cglib为您提供了一个静态工厂方法来创建新对象,但djcproxy要求您创建一个代理工厂。 这是在21上方的行上显示的。如果要像使用cglib一样使用它,则可以在要使用其工厂的类中声明一个静态ProxyFactory字段。 另一方面,可能在代码的不同部分具有不同的工厂。 尽管它的优点很少,但是我仍然相信它比提供静态工厂方法更干净。

代理如何工作?

此程序包中的另一件事是,它使您可以访问生成的源。 您可以插入行

String generatedSource = factory.getGeneratedSource();System.out.println(generatedSource);

打印出生成的代理类,这是经过某种格式设置的:

package com.javax0.djcproxy;class PROXY$CLASS$A extends com.javax0.djcproxy.ProxyFactoryTest.A implements com.javax0.djcproxy.ProxySetter {com.javax0.djcproxy.ProxyFactoryTest.A PROXY$OBJECT = null;com.javax0.djcproxy.MethodInterceptor PROXY$INTERCEPTOR = null;public void setPROXY$OBJECT(java.lang.Object PROXY$OBJECT) {this.PROXY$OBJECT = (com.javax0.djcproxy.ProxyFactoryTest.A) PROXY$OBJECT;}public void setPROXY$INTERCEPTOR(com.javax0.djcproxy.MethodInterceptor PROXY$INTERCEPTOR) {this.PROXY$INTERCEPTOR = PROXY$INTERCEPTOR;}PROXY$CLASS$A() {super();}private com.javax0.djcproxy.MethodProxy method_MethodProxyInstance = null;@Overridepublic int method() {try {if (null == method_MethodProxyInstance) {method_MethodProxyInstance = new com.javax0.djcproxy.MethodProxy() {public java.lang.Object invoke(java.lang.Object obj, java.lang.Object[] args) throws Throwable {return ((com.javax0.djcproxy.ProxyFactoryTest.A) obj).method();}};}return (int) PROXY$INTERCEPTOR.intercept(PROXY$OBJECT, PROXY$OBJECT.getClass().getMethod("method", new Class[]{}),new Object[]{}, method_MethodProxyInstance);} catch (Throwable e) {throw new RuntimeException(e);}}... other overridden methods deleted ...}

请注意,对于此生成的代码,类AProxyFactoryTest的静态嵌套类。

有趣的代码是方法method()的重载。 (对不起这个名字。对于一个什么都不做的方法,我有一个更好的名字。我不MethodProxy 。)让我们跳过该部分,检查该方法是否已经存在MethodProxy实例,如果缺少则创建一个。 方法method()实际上会调用我们定义的拦截器对象,并传递代理对象,反射方法对象,参数以及方法代理。

什么是方法代理

该名称可能首先引起混淆,因为我们已经有一个“对象”代理。 原始类的每个方法都有一个单独的方法代理。 这些可用于调用原始方法,而无需进行反射调用。 这加快了代理的使用。 您还可以在cglib中找到此调用和类似的机制。

笔记

该实现有一些流程,例如,后方法代理实例化实际上没有优势,但同时在代理的多线程执行情况下可能会受到损害。 还可以创建一个不仅扩展类而且实现任意接口的代理对象(也许某些扩展类甚至没有实现)。 该实现在github上也有一些其他业余爱好开源项目中使用,我将来可能会写有关该项目的信息。 它们比生产代码更具说明性,教育性和概念证明性项目。 如果您对实施,想法或任何意见有任何意见,请给我您的意见。

翻译自: https://www.javacodegeeks.com/2016/02/creating-proxy-object-using-djcproxy.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/356398.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

lightoj1145 【DP优化求方案】

题意&#xff1a; 有一个k面的骰子&#xff0c;然后问你n个骰子朝上的面数字之和s的方案&#xff1b;思路&#xff1a;dp[i][j] 代表 前 i 个骰子组成 j 有多少种方案&#xff1b;显然dp[i][j] dp[i - 1][j - 1] dp[i - 1][j - 2] ... dp[i - 1][j - k];我们算 dp[i][j] 的…

java rx.observable_Rxjava2 Observable的条件操作符详解及实例

简要&#xff1a;需求了解&#xff1a;在使用 Rxjava 开发中&#xff0c;经常有一些各种条件的操作 &#xff0c;如比较两个 Observable 谁先发射了数据、跳过指定条件的 Observable 等一系列的条件操作需求&#xff0c;那么很幸运&#xff0c; Rxjava 中已经有了很多条件操作符…

Linux poll 和 select 机制

poll select 介绍 使用非阻塞 I/O 的应用程序常常使用 poll, select, 和 epoll 系统调用. poll, select 和 epoll 本质上有相同的功能: 每个允许一个进程来决定它是否可读或者写一个 或多个文件而不阻塞. 这些调用也可阻塞进程直到任何一个给定集合的文件描述符可用来 读或写.…

hprof 不大 泄露_HPROF –内存泄漏分析教程

hprof 不大 泄露本文将为您提供有关如何通过生成和分析Sun HotSpot JVM HPROF堆转储文件来分析JVM内存泄漏问题的教程。 一个现实的案例研究将用于此目的&#xff1a;Weblogic 9.2内存泄漏影响Weblogic Admin服务器。 环境规格 Java EE服务器&#xff1a;Oracle Weblogic Ser…

java枚举怎么编译不行的_java枚举类型

public classTestEnum {/*最普通的枚举*/public enumColorSelect {red, green, yellow, blue;}/*枚举也可以象一般的类一样添加方法和属性,你可以为它添加静态和非静态的属性或方法,这一切都象你在一般的类中做的那样.*/public enumSeason {//枚举列表必须写在最前面&#xff0…

eclipse光标变成黑块变粗解决办法

就是按下了键盘的insert按键转载于:https://www.cnblogs.com/panxuejun/p/6170717.html

投资银行对Java进行的二十大核心面试问答

这是在金融领域&#xff08;主要是大型投资银行&#xff09;共享Java核心访谈问题和答案的新系列。 在JP Morgan&#xff0c;Morgan Stanley&#xff0c;Barclays或Goldman Sachs上会问许多这些Java面试问题。 银行主要从多线程 &#xff0c; 集合 &#xff0c;序列化&#xff…

java 支付重复问题_Airbnb支付系统如何在分布式环境下避免重复打款

原文链接&#xff1a;https://medium.com/airbnb-engineering/avoiding-double-payments-in-a-distributed-payments-system-2981f6b070bbAirbnb一直在将其基础架构迁移到面向服务的体系结构(SOA)。 SOA具有许多优势&#xff0c;例如使开发人员能够专业化并具有更快迭代的能力。…

用注解方式写定时任务

spring里加上 </context:component-scan><!-- 任务自动扫描 --><task:annotation-driven/><!-- 扫描位置 --><context:annotation-config/> <context:component-scan base-package"com.xxx.xxx"/>然后在类上面添加注解 Compon…

myeclipse配置java8_MyEclipse 2017配置Tomcat8

MyEclipse 2017的配置其实跟MyEclipse 2015的比较一致&#xff0c;再往之前的就有出入了。不得不吐槽其卡&#xff0c;跟Eclipse不在一个量级上呀。。。一、配置转自&#xff1a;http://www.xuexila.com/diannao/diy/2788109.html工具/原料myeclipse 2017tomcat8 服务器方法/步…

moxy json介绍_MOXy作为您的JAX-RS JSON提供程序–服务器端

moxy json介绍在之前的系列文章中&#xff0c;我介绍了如何利用EclipseLink JAXB&#xff08;MOXy&#xff09;创建RESTful数据访问服务。 在本文中&#xff0c;我将介绍在服务器端利用MOXy的新JSON绑定添加对基于JAXB映射的JSON消息的支持有多么容易。 MOXy作为您的JAX-RS JSO…

mysql教程清华课后答案_mysql学习之路_sql

查看数据库&#xff1a;Show databases;查看指定部分数据库&#xff1a;模糊查询Show databases like ‘patten’;--paatten是匹配模式%&#xff1a;表示是匹配模式_&#xff1a;表示匹配单个字符&#xff1b;查看数据库创建语句&#xff1a;Show create database 数据库名[库选…

那么您想做微服务吗? 请观看微服务以防万一

Bert Ertman在本次有关微服务的演示中提供了许多有效的观点。 您是否正在考虑在项目&#xff0c;团队或公司中遵循此路径&#xff1f; 请拿起咖啡&#xff0c;记事本&#xff08;如果您喜欢手写笔记&#xff09;并观看。 看到许多公司和团队确实很痛苦&#xff0c;精力浪费&…

MDX中Filter 与Exist的区别

获得一个集合&#xff0c;这个一般用来筛选出一个自定义的set&#xff0c;比如在中国的餐厅 该set返回所有MSDNteam下并且在Fact Thread度量上有记录的products 用Exists实现 select Exists( [Dim Queue].[Product - Queue].MEMBERS, [Dim Engineer].[Team - Engineer].[Team N…

java chsftp.get 追加_Java SFTP上传使用JSch,但如何覆盖当前文件?

我试图使用JSch将两个文件上传到具有SFTP的服务器.如果目录为空,则上传文件可以正常工作,但我想一遍又一遍地上传相同的文件(只需更改内部的id),但是我无法弄清楚如何做到这一点. JSch中有一些静态参数叫做OVERWRITE,但是我无法找到如何使用它.任何人都关心我如何添加这个设置&…

MySQL在Django框架下的基本操作(MySQL在Linux下配置)

注&#xff1a;本文已迁移至CSDN&#xff0c;后续的更新也会在CSDN。 http://blog.csdn.net/houchaoqun_xmu/article/details/53813633 http://blog.csdn.net/houchaoqun_xmu 【原】本文根据实际操作主要介绍了Django框架下MySQL的一些常用操作&#xff0c;核心内容如下&#x…

Clean Sheet – Windows 10的人体工程学Eclipse主题

Clean Sheet是适用于Windows 10的符合人体工程学的Eclipse主题。它基于干净&#xff0c;低眩光的外观和感觉&#xff0c;旨在减轻视觉疲劳和眼睛疲劳。 它融合了均衡的颜色选择&#xff0c;可以突出谐波语法并注重可读性。 除自定义滚动条外&#xff0c;它还努力满足现代美学要…

php mysql插入的数据有引号_php – 由于’引号’的不同,数据没有插入到mysql数据库中...

您不需要在查询中封装表,除非它们有空格或者它们是保留字.INSERT INTO lms.test2 (trn) VALUES (17)// This makes no real sense to the db. It should be:INSERT INTO lms.test2 (trn) VALUES (17)如果列trn接受数字,它应该是&#xff1a;INSERT INTO lms.test2 (trn) VALUES…

CentOS上安装MyCat-MySQL

1、安装JDK&#xff0c;要求JDK7以上。 2、下载MyCat&#xff0c;地址。 3、解压Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz&#xff0c;到usr/local/Mycat目录下。 4、添加用户Mycat。 [rootlocalhost Desktop]# useradd Mycat [rootlocalhost Desktop]# passwd M…

Java中的Redis的思维导图_Redis思维导图

常见相关问题Redis 有哪些功能&#xff1f;数据缓存功能分布式锁的功能支持数据持久化支持事务支持消息队列Redis 为什么是单线程的&#xff1f;因为 cpu 不是 Redis 的瓶颈&#xff0c;Redis 的瓶颈最有可能是机器内存或者网络带宽。既然单线程容易实现&#xff0c;而且 cpu 又…