Java Top.

使用Spring 5和Spring Boot 2开始,通过学习春天课程:

>>查看课程

1.介绍

这篇文章是关于金宝搏官网188beJava的动态代理- 这是语言中可用的主要代理机制之一。

简单地,代理是通过自己的设施(通常在真实方法上)通过功能调用的前线或包装器 - 可能添加一些功能。

动态代理允许一个单个类,单个方法将多个方法服务多个方法调用任意数量的方法。动态代理可以被认为是一种正面,但可以假装是任何界面的实现的人。在封面下,它将所有方法调用路由到单个处理程序- 这invoke()方法。

虽然它不是用于日常编程任务的工具,但动态代理对框架作家非常有用。它也可以用于在那些情况下,在运行时不会知道具体阶级实现的情况下。

此功能内置于标准JDK中,因此不需要额外的依赖项。

2.调用处理程序

让我们构建一个简单的代理,除了打印要调用的方法并返回硬编码的数字后,除了打印什么方法。

首先,我们需要创建一个子类型java.lang.reflect.InvocationHandler.

公共类DynamicInvocationHandler实现InvocationHandler {私有静态记录记录器= loggerFactory.getLogger(DynamicInVocationHandler.class);@override public对象调用(对象代理,方法方法,对象[] args)抛出throwable {logger.info(“调用方法:{}”,method.getname());返回42;}}

在这里,我们定义了一个简单的代理,该代理是调用哪种方法并返回42的日志。

3.创建代理实例

由我们刚定的调用处理程序服务的代理实例是通过工厂方法调用创建的java.lang.reflect.proxy.班级:

地图proxyinstance =(map)proxy.newproxyinstance(dynamicproxytest.class.getclassloader(),new class [] {m​​ap.class},new dynamicinvocationHandler());

一旦我们有一个代理实例,我们可以像正常一样调用其接口方法:

proxyinstance.put(“Hello”,“World”);

正如预期的信息金宝搏官网188be放()调用的方法在日志文件中打印出。

4.通过Lambda表达式调用处理程序

自从invocationHandler.是一个功能界面,可以使用lambda表达式来定义处理程序内联:

地图proxyinstance =(map)proxy.newproxyinstance(dynamicproxytest.class.getclassloader(),new class [] {m​​ap.class},(代理,方法,profortargs) - > {if(方法.get.getname()。等于(“get“)){返回42;} else {投掷新的UnsupportedoperationException(”不支持的方法:“+ method.getname());}});

在这里,我们定义了一个处理程序,返回所有获取操作并抛出的处理程序UnsupportedoperationException.对于其他一切。

它以完全相同的方式调用:

(int)proxyinstance.get(“Hello”);// 42 proxyinstance.put(“你好”,“世界”);// 例外

5.时序动态代理示例

让我们来检查一个潜在的现实世界场景,用于动态代理。

假设我们想录制我们的函数需要多长时间。在这种程度上,我们首先定义能够包装“真实”对象的处理程序,跟踪定时信息和反射调用:

公共类TimingDynamicInvocationHandlinder实现InvocationHandler {私有静态记录记录器= loggerFactory.getLogger(timingdynamicinvocationHandlar.class);私人最终地图<字符串,方法>方法= new hashmap <>();私有对象目标;public timingdynamicinvocationHandler(对象目标){this.target = target;for(方法方法:target.getClass()。getDeclaredMethods()){this.methods.put(method.getname(),方法);@Override public对象调用(对象代理,方法方法,对象[] args)抛出throwable {long start = system.nanotime();对象结果=方法。重点(方法.getName())。调用(目标,args);长期= system.nanotime() - 开始;logger.info(“执行{}在{} ns中完成”,percormate.getName(),已过去);返回结果; } }

随后,可以在各种对象类型上使用此代理:

地图Mapproxyinstance =(地图)Proxy.Newproxyinstance(DynamicProxytest.Class.getClassLoader(),新类[] {m​​ap.class},新的timingdynamicinvocationHandher(new hashmap <>()));mapproxyinstance.put(“你好”,“世界”);charsequence csproxyinstance =(charsequence)proxy.newproxyinstance(dynamicproxytest.class.getclassloader(),new class [] {charsequence.class},new timingdynamicinvocationHandher(“Hello World”));csproxyinstance.length()

在这里,我们已经提出了一个地图和char序列(字符串)。

代理方法的调用将委派给包装对象以及生成日志记录语句:

在19153 NS执行完成于8891 NS的ECT完成在11152 NS执行的Charat中完成的执行完成于10087 ns完成

六,结论

在此快速教程中,我们已检查Java的动态代理以及其中一些可能的使用。

一如既往,可以找到示例中的代码在github上

Java底部

使用Spring 5和Spring Boot 2开始,通过学习春天课程:

>>查看课程
评论在本文上关闭!