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

java动态代理java静态代理和动态代理

2天前CN2资讯

1. 简介

java的动态代理功能是用来解决现有类功能不足,但我们又不想去修改现有类方法的问题,或者就是我们无法直接使用现有类的情况。它的实现方式有两种,第一种是jdk自带的动态代理功能,它的实现前提是现有类必须拥有一个接口,因为它是通过对现有类接口的实现来完成的。第二种方式是cglib,这是一个开源工具包,它的实现是通过继承现有类,然后重写现有类的方法实现的。它们在spring与mybatis框架中均有使用。学习它们的前提是你要对java的反射机制有一定的认知。本篇只介绍jdk原生的动态代理。

2. jdk动态代理

2.1 演示前景

客户:购买u盘

代理商:淘宝

u盘工厂:金士顿,三星等

用户想要购买u盘,是不可以直接去厂家购买的,需要通过淘宝等代理商进行购买,抽象成程序就是,u盘工程就是目标类,也就是现有类,淘宝就是代理类,客户就是用户类.用户需要调用淘宝的方法进行购买u盘,而淘宝又需要调用工厂的方法进行购买.如果我们直接创建一个淘宝类,让它去代理金士顿工厂,就会出现一个问题,那就是三星工厂由谁去代理,总不能再创建一个代理类吧,所以就可以使用动态代理的方式,在程序运行时期,根据不同的情况去创建一个合适的代理类

 

2.2编写代码

首先我们需要一个工厂的接口UsbFactory

package com.hzq.application.targetclass;
public interface UsbFactory { //售卖u盘,并返回实际价格的方法 float sell(int num);}  

第二步就是创建一个UsbFactory的实现类UsbKingFactory代表金士顿工厂

package com.hzq.application.targetclass.impl;
import com.hzq.application.targetclass.UsbFactory;
public class UsbKingFactory implements UsbFactory { @Override public float sell(int num) { float onePrice = 30.0F; float price = onePrice * num; System.out.println("向厂家购买花费了"+price+"元"); return price; }}  

现在需要我们代理的目标类已经好了,接下来就是重点了,jdk动态代理的实现方法(这个实现套路是固定的)。第三步,创建一个MyInvocationHandler类去实现接口InvocationHandler。这个接口只有一个需要我们去实现的方法,那就是invoke()方法,它有3个参数,第一个参数其实就是我们后面通过动态代理去创建的代理类,这个参数不需要我们的参与,不用去理会,第二个参数是我们要去增强的目标类的方法,第三个是该方法的参数.invoke内部就是我们要对目标类的方法增强的具体逻辑,也就是我们想怎样去增强它,在本示例中我们是对用户购买的商品收取20元中介费,然后送给用户一张10元的优惠券

package com.hzq.application.proxy;
import com.hzq.application.targetclass.UsbFactory;
import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;
public class MyInvocationHandler implements InvocationHandler { private UsbFactory factory ; @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //1.调用目标类的售卖方法,然后返回价格 Float price = (Float) method.invoke(factory, args); //2.我们在之后进行自定义的增强,这里我们是抽取20元的中介费用,然后送给客户一张10元优惠券 price += 20; System.out.println("代理商送您一张10元优惠券"); System.out.println("客户购买商品花费了"+price+"元"); return price; }
public MyInvocationHandler(UsbFactory factory) { this.factory = factory; }}    

最后一步就是去使用jdk动态代理来在运行期创建一个代理类对象了,在代码中第第三步是重点,我们如果我们想要创建一个动态代理类,就必须要调用Proxy类的静态方法newProxyInStance()方法,这个方法会返回给我们一个代理类对象,我们实际购买商品也是通过这个代理类来进行购买的。newProxyInstance()方法一共有三个参数,第一个参数是一个类加载器对象,类加载器对象可以通过目标类的Class对象去调用getClassLoader()方法去获取,其实也可以使用其他你自定义的类的Class对象去获取,因为最后获得的都是同一个类加载器实例,但为了代码的易读性,就使用了目标类。第二个参数是目标类的接口类型,第三个参数就是我们自定义的MyInvocationHandler类的实例对象了,它里面封装这我们具体的增强逻辑代码。方法调用完成后,如果没有出现问题就会返回给我们一个代理类的实例,之后我们就可以去使用这个代理类的。

package com.hzq.application;
import com.hzq.application.proxy.MyInvocationHandler;import com.hzq.application.targetclass.UsbFactory;import com.hzq.application.targetclass.impl.UsbKingFactory;
import java.lang.reflect.InvocationHandler;import java.lang.reflect.Proxy;
public class ProxyMain { public static void main(String[] args) { //1.实例化一个金士顿工厂对象 UsbFactory usbFactory = new UsbKingFactory(); //2.实例化一个MyInvocationHandler对象 InvocationHandler handler = new MyInvocationHandler(usbFactory); //3.通过jdk动态代理创建出代理对象 UsbFactory proxyInstance = (UsbFactory) Proxy.newProxyInstance(usbFactory.getClass().getClassLoader(), usbFactory.getClass().getInterfaces(), handler); //4.通过代理对象来购买商品 float price = proxyInstance.sell(3); System.out.println(price); }}  

最后,当我们需要代理其他工厂去售卖u盘时,只需要将main方法中的第一步实例化的金士顿工厂改成其他品牌的工厂即可,当然前提是这个工厂的类实现了UsbFactory接口。

2.3 总结

当我们去使用jdk动态代理时,首先需要确保目标类实现了接口。之后的使用步骤就是:

  • 实现InvocationHandler接口,将我们具体的增强逻辑代码写在invoke()方法中

  • 使用Proxy类的newProxyInstance()方法去创建一个代理类的实例对象.

  • 使用这个代理类对象

    • 你可能想看:

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

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

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

      分享给朋友:

      “java动态代理java静态代理和动态代理” 的相关文章

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

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

      Windows SSH Client安装与配置指南

      在Windows 10版本1809及以后的版本中,微软引入了OpenSSH客户端,这让很多用户的远程管理变得更为便捷。作为一个IT爱好者,我发现这个特性非常有用,它让我能够轻松地通过SSH协议安全地连接和管理远程服务器。接下来,我将分享一些Windows SSH客户端的安装和配置过程,方便大家快速上...

      选择香港主机的最佳指南:提升您的网站性能与用户体验

      香港主机指的是那些在香港地区部署的服务器,主要用于提供网站托管、应用托管或数据库管理等服务。得益于香港卓越的网络基础设施,越来越多的企业和个人选择将他们的运营托付给香港主机。这不仅提升了业务的可达性,也提供了更优质的用户体验。 如果我回想起我最初接触香港主机时,感到非常惊讶于它的潜力。香港地理位置独...

      选择日本不限流量VPS的最佳方案与优化建议

      日本不限流量VPS市场现状 日本的VPS市场,尤其是不限流量的产品,正迎来一个快速发展的阶段。随着互联网技术的进步,亚洲的网络环境发生了翻天覆地的变化。尤其是在日本,不限流量VPS因其连接速度快、数据中心服务优质而广受欢迎,对那些需要持续大流量的网站运营者来说,这可是一个无与伦比的选择。 我发现,随...

      如何开启BBR查询并提升TCP网络性能

      BBR(Bottleneck Bandwidth and Round-trip propagation time)是一种由Google开发的TCP拥塞控制算法,我对它的了解让我感到非常兴奋。BBR旨在通过精确的网络条件监测,以提高传输速度和稳定性。传统的拥塞控制算法往往依赖于丢包率的变化来调整传输速...

      搬瓦工VPS:初学者的最佳选择与使用指南

      大家对VPS可能不太熟悉,搬瓦工VPS在整个市场中已经站稳了脚跟。作为加拿大IT7公司旗下的一款主机服务,搬瓦工以其性价比高的OpenVZ VPS起步,而现在主要以KVM架构为主流,逐渐发展成为国内用户的热门选择。这种转型让我觉得很有意思,因为它不仅仅是一种产品的升级,更是一种服务的提升。 搬瓦工提...