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

java代理java反向代理

1天前CN2资讯
java中的代理Proxy

代理为什么使用代理,代理的主要作用就可以在不改动原有代码的基础上给原有对象添加新的功能,实现的方法是被代理类和代理类继承同一个类或者实现了同一个接口,java中代理分为静态代理和动态代理:

1.静态代理

静态代理中的静态主要表现在代理类是在提前写好的,也可以说所使用的代理在程序运行开始之前就知道,代理对象是通过new出来的。我们的被代理对象是一个自行车,后面对车进行了升级,可以在上面使用电动的骑行。

Machine.java

public interface Machine { void drive(); }

Bicycle.java

public class Bicycle implements Machine{ private String name; public Bicycle() { = "人力"; } public String getName() { return name; } public void setName(String name) { = name; } @Override public void drive() { System.out.println("我正在使用"++"骑行"); } }

EleBicycle.java

public class EleBicycle implements Machine{ private Bicycle bicycle; public EleBicycle(Bicycle bicycle) { this.bicycle = bicycle; } @Override public void drive() { System.out.println("现在升级了电力,可以用电力骑行"); this.bicycle.setName("电力"); this.bicycle.drive(); } }

People.java

public class People { public static void main(String[] args) { Bicycle bicycle = new Bicycle(); bicycle.drive(); // 使用代理 Machine bicycleProxy = new EleBicycle(bicycle); bicycleProxy.drive(); } }

他们直接的关系可以看成如图所示,自行车(Bicycle)和加了电的自行车(EleBicycle)分别是被代理的对象和代理,他们都实现了Machine这个接口,然后People这个用户来消费这个产品。

通过上面的例子可以明显看出来使用代理的好处就是当我们需要对我们的类进行功能升级时不用直接在写好的类上面重新加功能代码,因为可能在有的地方是需要升级过的类,有的地方是需要未升级的类。使用代理的方式也使代码得到了复用。但使用静态代理也存在一些缺点:使用静态代理需要我们在代码运行之前就需要知道用户需要新加的功能是在那个代理类里面,但在实际开发中会存在在开发的时候,开发人员不知道用户需要的操作要使用哪个代理类,只有当用户点击页面时才知道用户所要使用的代理类,这种代理也就是我们所要学到的动态代理。

2.动态代理

动态代理的使用情景在于开发人员无法在程序运行开始前知道用户所要使用的代理是那个,这种在程序运行中创建对象的方法自然就想到了反射。在java的动态代理中最重要的是一个接口InvocationHandler,我们的代理类要实现这个接口同时重写其中的invoke()方法,和一个Proxy类中的newProxyInstance()静态方法用来动态的创建代理类。动态代理中的代理类不要我们手动写,只需要些一个实现了InvocationHadler接口的类,通过Proxy会自动根据我们的handler来创建代理类。

Hello.java

public interface Hello { public String hello(); public String bye(); }

HelloWorld.java

public class HelloWorld implements Hello{ @Override public String bye() { System.out.println("这是被代理对象中的bye"); return "bye"; } @Override public String hello() { System.out.println("这是被代理对象中已有的方法"); return "hello"; } }

WorkHandler.java

import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class WorkHandle implements InvocationHandler { // 被代理的对象 private Object object; // 代理类的构造方法用于给被代理类实例赋值 public WorkHandle(Object object) { this.object = object; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("代理类中的新功能"); if(method.getName()=="bye"){ System.out.println("代理类中的bye"); } Object invoke = method.invoke(object,args); return invoke; } public static void main(String[] args) { Hello people = new HelloWorld(); InvocationHandler invocationHandler = new WorkHandle(people); Hello proxy = (Hello) Proxy.newProxyInstance(invocationHandler.getClass().getClassLoader(), people.getClass().getInterfaces(), invocationHandler); String hello = proxy.hello(); System.out.println(hello); String bye = proxy.bye(); System.out.println(bye); } }

上面就是一个动态代理的实现过程,我们还可以写不同的handler,运行中可以根据不同的handler来实现不同的代理。下面将Proxy和InvocationHandler展开细看。

1.Proxy类

其中的newProxyInstance()

@CallerSensitive // 类加载器,实现的接口,handler public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException { Objects.requireNonNull(h); final Class<?>[] intfs = interfaces.clone(); final SecurityManager sm = System.getSecurityManager(); if (sm != null) { checkProxyAccess(Reflection.getCallerClass(), loader, intfs); } /* * Look up or generate the designated proxy class. */ Class<?> cl = getProxyClass0(loader, intfs); /* * Invoke its constructor with the designated invocation handler. */ try { if (sm != null) { checkNewProxyPermission(Reflection.getCallerClass(), cl); } final Constructor<?> cons = cl.getConstructor(constructorParams); final InvocationHandler ih = h; if (!Modifier.isPublic(cl.getModifiers())) { AccessController.doPrivileged(new PrivilegedAction<Void>() { public Void run() { cons.setAccessible(true); return null; } }); } // 通过获取的构造方法来生成类的对象,即代理对象 return cons.newInstance(new Object[]{h}); } catch (IllegalAccessException|InstantiationException e) { throw new InternalError(e.toString(), e); } catch (InvocationTargetException e) { Throwable t = e.getCause(); if (t instanceof RuntimeException) { throw (RuntimeException) t; } else { throw new InternalError(t.toString(), t); } } catch (NoSuchMethodException e) { throw new InternalError(e.toString(), e); } }

2.InvocationHandler

//里面就一个待实现的invoke()方法 public interface InvocationHandler{ public Object invoke(Object proxy,Method method,Object[] args) throws Throwable; }

知之为知之,不知为不知
    你可能想看:

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

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

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

    标签: java代理Java
    分享给朋友:

    “java代理java反向代理” 的相关文章

    如何选择RN套餐性价比高的VPS服务

    RN套餐概述 在谈论RackNerd之前,我想先简单介绍一下这家公司。RackNerd成立于2019年,它是一家专注于虚拟主机和VPS服务的商家。作为市场中的新兴参与者,RackNerd凭借其高性价比迅速赢得了不少用户的青睐。在我了解的多家VPS提供商中,RackNerd以其实惠的价格和稳定的性能脱...

    ExtraVM测评:美国优质VPS服务全面解析

    在美国,ExtraVM是一家备受关注的主机商,提供的VPS方案在业内小有名气。这家企业不仅因其强大的硬件配置而受到用户热爱,还因为具备高带宽和强大防御能力而赢得了良好的口碑。对于许多站长来说,这里就像是一块“宝地”,能够满足他们各种需求。 当我第一次了解ExtraVM的时候,我被其在洛杉矶的数据中心...

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

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

    VPS优惠活动解析:如何选择最划算的虚拟专用服务器方案

    在当今互联网环境中,VPS(虚拟专用服务器)为企业和个人用户提供了灵活、高效的解决方案。随着云计算的普及,VPS逐渐成为许多用户的首选。不管是建站、开发、还是日常的数据处理,选择一款合适的VPS至关重要。而在不同的VPS服务提供商中,优惠活动往往能让用户以更实惠的价格体验高质量的服务。 什么是VPS...

    RackNerd Windows VPS的硬件条件与性能评测

    在选择虚拟服务器服务商时,硬件条件是我最关注的部分。RackNerd作为一家提供多种配置Windows VPS的服务商,其硬件条件非常吸引。接下来,我将详细介绍RackNerd在硬件配置方面的一些关键特点。 处理器配置 RackNerd使用的AMD Ryzen 3900X处理器,让人印象深刻。这个处...

    亿速云:构建安全、高效的云计算解决方案

    在当今数字化快速发展的时代,云计算服务的重要性愈发显著。我了解到,亿速云正是一家在这一领域崭露头角的企业,专注于提供高品质的云计算服务。自成立以来,亿速云围绕创新技术和卓越服务,努力帮助各行各业的用户实现数字化转型和升级。作为新一代云计算服务商,亿速云把握时代脉搏,致力于为全球用户提供稳定、安全、高...