当前位置:首页 > CN2资讯 > 正文内容

Java JDK动态代理java jdk官网

1天前CN2资讯

Java JDK动态代理

  • 前言
  • 必须理解和掌握的前提概念:
  • 如何实现JAVA JDK动态代理
    • 掌握了基本前提概念之后,还有几点我们需要进行明确的。
    • Java JDK动态代理
    • 实例
      • IAbstractUserDAO
      • UserDAO
      • DAOLogHandler
      • Client
  • 参考资料:
  • 如果博主的文章对您有所帮助,可以评论、点赞、收藏,支持一下博主!!!
前言

本篇文章主要讲解的是什么是JAVA JDK版本的动态代理,如何使用JAVA JDK版本的动态代理。对于JAVA JDK版本的动态代理的原理不会过多的描述。本篇文章旨在如果使用JDK动态代理。

必须理解和掌握的前提概念:

为了更好的掌握和使用JDK 动态代理需要了解一下概念。

1.什么是代理(proxy)

例如:由于客户端不想活着不能直接访问一个对象,此时可以通过一个称为代理的第三者来实现简介访问对象,这个过程为一个代理。

更加生活化的实例是:
例如:代购,如:在当地买不到某件商品,又或者因为当地的这件商品的价格比其他地区的贵,所以托人或者机构在其他地区购买该商品,并携带回来。

2.静态代理和动态代理

可以提前学习一下设计模式中的代理模式,会对一下内容会有一个更深的理解。

静态代理:传统的代理模式中客户端通过Proxy类调用RealSubject类和方法,同时还在代理类还可以封装其他方法。如果按照这种方法使用代理模式,那么代理类和真实主题类都应该是事先已经存在,代理类的接口和所代理方法都已明确制定。每一个代理类在编译之后都会生成一个class文件,代理类说实现的接口和所代理的方法,都被固定,这种代理称为静态代理。

静态代理的局限性:如果需要为不同的真实主题类提供代理类或者代理一个真实主题类的不同方法,都需要增加新的代理类,这将导致系统中的类个数急剧增加,因此需要想办法减少系统中类的个数。

动态代理(dynamic proxy)可以让系统在运行时根据实际需要来动态创建代理类,让同一个代理类能够代理多个不同的RealSubject而且可以代理不同的方法。
JDK中提供的动态代理智能代理一个或者多个接口,如果需要动态代理具体类或者抽象类,可以是用CGLib(Code Generation Library)等工具

如何实现JAVA JDK动态代理

掌握了基本前提概念之后,还有几点我们需要进行明确的。

先看代理模式简易版类图:

1.为了让客户端能够一致性的对待RealSubject对象和Proxy对象,引入抽象类Subject
2.为了保持行为的一致性,Proxy和realSubject通常会实现相同的接口
3.对于接口的理解:接口这个术语有多个意思,1.接口(API)某个类的接口或该类持有的方法的集合。2.使用关键字interface声明的代码。
—————————————————————————————————————————————

Java JDK动态代理

从JDK1.3开始,java语言提供了对动态代理的支持,java语言实现动态代理时需要用到位于java.lang.reflect包中的一些类。

1.Proxy类

proxy类提供了用于创建动态代理类和实例对象的方法,他是说创建的动态代理类的父类。
常用方法:

public static Class<?> getProxyClass(ClassLoader loader, Class<?>... interfaces)

该方法用于返回一个Class类型的代理类,在参数中需要提供类加载器并需要指定代理的接口数组(与真实主题类的接口列表一致)。

public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)

该方法用于返回一个动态创建的代理类的实例,方法中的第一个参数loader表示代理类的类加载器,第二个参数interfaces表示代理类所实现的接口列表(与真实主题类的接口列表一致),第三个参数h表示所指派的调用处理程序类。

2.InvocationHandler接口

InvocationHandler接口是代理处理程序类的实现接口,该接口作为代理实例的调用处理者的公共父类,每一个代理类的实例都可以提供一个相关的具体调用处理者(InvocationHandler接口的子类)。在该接口中声明了如下方法:

public Object invoke(Object proxy, Method method, Object[] args)

该方法用于处理对代理类实例的方法调用并返回相应的结果,当一个代理实例中的业务方法被调用时将自动调用该方法。invoke()方法包含3个参数,其中第一个参数proxy表示代理类的实例,第二个参数method表示需要代理的方法,第三个参数args表示代理方法的参数数组。

动态代理类需要在运行时指定所代理真实主题类的接口,客户端在调用动态代理对象的方法时调用请求会请求自动转发给InvocationHandler对象的invoke()方法,有invoke()方法来实现对请求的统一处理。

实例

某软件公司要为公司SPM系统数据卷访问层DAO增加方法调用日志,记录每一个方法被调用的时间和调用结果,现在使用动态代理进行设计和实现。

代码结构:总共有四个类

IAbstractUserDAO

package test; /** * @author : [WangWei] * @version : [v1.0] * @className : ISubject * @description : [抽象用户DAO类,抽象主题类] * @createTime : [2022/9/18 8:27] * @updateUser : [WangWei] * @updateTime : [2022/9/18 8:27] * @updateRemark : [描述说明本次修改内容] */ public interface IAbstractUserDAO { public Boolean findUserById(String userId); }

UserDAO

package test; /** * @author : [WangWei] * @version : [v1.0] * @className : RealSubject * @description : [用户DAO类,具体主题类] * @createTime : [2022/9/18 8:27] * @updateUser : [WangWei] * @updateTime : [2022/9/18 8:27] * @updateRemark : [描述说明本次修改内容] */ public class UserDAO implements IAbstractUserDAO { @Override public Boolean findUserById(String userId) { return null; } }

DAOLogHandler

package test; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.util.Calendar; import java.util.GregorianCalendar; /** * @author : [WangWei] * @version : [v1.0] * @className : InvocationHandlerImpl * @description : [请求处理程序类] * @createTime : [2022/9/18 8:31] * @updateUser : [WangWei] * @updateTime : [2022/9/18 8:31] * @updateRemark : [描述说明本次修改内容] */ public class DAOLogHandler implements InvocationHandler { private Calendar calendar; private Object subject; //自定义有参构造函数,用于注入一个需要提供代理的真实主题对象 public DAOLogHandler(Object subject) { this.subject = subject; } /* * @version V1.0 * Title: invoke * @author Wangwei * @description 实现invoke()方法,调用在真实主题类中定义的方法 * @createTime 2022/9/25 10:21 * @param [proxy, method, args] * @return java.lang.Object */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //调用记录方法调用时间 this.beforeInvoke(); Object result =method.invoke(subject,args);//转发调用 //标记方法调用结束 this.afterInvoke(); return result; } //记录方法调用时间 private void beforeInvoke(){ calendar=new GregorianCalendar(); int hour=calendar.get(Calendar.HOUR_OF_DAY); int minute=calendar.get(Calendar.MINUTE); int second=calendar.get(Calendar.SECOND); String time=hour+":"+minute+":"+second; System.out.println("调用时间:"+time); } private void afterInvoke(){ System.out.println("方法调用结束"); } }

Client

package test; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; /** * @author : [WangWei] * @version : [v1.0] * @className : DynamicProxyDemonstration * @description : [客户端测试类] * @createTime : [2022/9/18 8:36] * @updateUser : [WangWei] * @updateTime : [2022/9/18 8:36] * @updateRemark : [描述说明本次修改内容] */ public class Client { public static void main(String[] args) { InvocationHandler handler=null; IAbstractUserDAO userDAO=new UserDAO(); handler=new DAOLogHandler(userDAO); IAbstractUserDAO proxy=null; //动态创建代理对象,用于代理一个IAbstractUserDAO类型的真实对象 proxy=(IAbstractUserDAO) Proxy.newProxyInstance(IAbstractUserDAO.class.getClassLoader(),new Class[]{IAbstractUserDAO.class},handler); proxy.findUserById("David"); } } 参考资料:

Java JDK 动态代理(AOP)使用及实现原理分析
书籍:《java设计模式》–刘伟

如果博主的文章对您有所帮助,可以评论、点赞、收藏,支持一下博主!!!
    你可能想看:

    扫描二维码推送至手机访问。

    版权声明:本文由皇冠云发布,如需转载请注明出处。

    本文链接:https://www.idchg.com/info/24953.html

    分享给朋友:

    “Java JDK动态代理java jdk官网” 的相关文章

    APT是什么?高级持续性威胁的定义与防御策略

    APT是指高级持续性威胁(Advanced Persistent Threat),它代表了一种针对特定目标进行的长期和有计划的网络攻击。这种攻击的高端特征在于,攻击者会在施加攻击之前,详细调查并了解攻击对象的业务流程和系统架构。换句话说,APT并不是一种简单随机的攻击,而是通过深入分析和细致的侦查工...

    远程VPS优选指南:高效管理虚拟专用服务器的最佳实践

    随着远程工作的普及和数字化转型的加速,远程VPS(虚拟专用服务器)逐渐成为许多企业和个人的首选工具。VPS通过虚拟化技术,让我们能够在一台物理服务器上同时运行多个独立的操作系统,这种灵活性使得用户能够像管理独立服务器那样,远程登录和管理自己的虚拟环境。每天都有更多的人意识到,拥有一个VPS可以为他们...

    如何在Vultr上添加适合的充值金额和选择合适的VPS方案

    Vultr概述 Vultr是一家在云服务领域颇有声誉的公司,它以提供高性能的虚拟专用服务器(VPS)而闻名。Vultr不仅在全球范围内拥有多个数据中心,还以其灵活的方案和易于扩展的功能,赢得了众多用户的青睐。在激烈的市场竞争中,Vultr凭借其合理的价格和优化的服务流程,使自己脱颖而出,成为许多个人...

    深入了解DMIT不同线路,优化您的网络体验

    在开始深入了解DMIT这一知名VPS提供商之前,我想先分享一下我对于它的初步印象。DMIT的使命是为用户提供高性能、稳定的VPS解决方案,特别是在跨境访问方面表现不俗。他们采用的CN2优化线路更是让其在众多竞争对手中脱颖而出。通过不断的发展与创新,DMIT为不同需求的用户提供了多种线路选择。 DMI...

    搬瓦工中文网:轻松掌握VPS服务与网络加速技巧

    当我第一次听到“搬瓦工”这个名字时,感觉它似乎很神秘,直觉告诉我,这背后一定有许多有趣的内容。经过一番了解后,我发现搬瓦工其实是一款基于VPS(虚拟专用服务器)的服务,主要帮助用户实现网络加速与资源的灵活使用。简而言之,搬瓦工让用户能够在更广阔的网络环境中畅游,不受地理限制。 搬瓦工的功能非常多样,...

    /16子网掩码的配置与应用指南 | 实现高效网络管理

    为什么选择/16的子网掩码 选择/16的子网掩码常常让人感到有些陌生。对我来说,这个数字不仅仅是一个技术参数,它蕴含着网络设计的深刻意义。首先,子网掩码的基本概念就如同我们在城市中划分区域,/16实际上表示有65536个可用IP地址。这么广阔的空间对于需要大量设备联网的环境,如企业或大型组织,尤其重...