java代理模式详解,java代理模式的典型例子,java代理模式(jdk proxy)

java代理模式详解,java代理模式的典型例子,java代理模式(jdk proxy)

代理是一种设计模式,它提供了另一种访问目标对象的方式。本文主要介绍Java中的三种代理模式。有需要的朋友可以参考一下,希望能帮到你。

目录

什么是代理?给我举个栗子?什么是代理模式?如何实现代理?静态代理?根据以上流程,分析静态剂的优缺点。动态代理CGLIB代理jdk代理InvocationHandler接口方法类代理类JDK动态代理实现步骤摘要

什么是代理

举个栗子

比如有一所美国大学,可以招收世界各地的学生。但是对于家长来说,家长不能直接去学校,家长不能直接去学校参观,或者美国学校不接受个人参观,那么就需要一个留学中介来帮助这个美国学校招生。

学生,中介是学校的代理人。和中介学校要做的一样:招生。对于家长来说,学校是目标,学习代理是代理。日常生活中,代理的例子很多,代购、房产中介、各种中介、ip交易所、商家、厂家、买家。发展中

也有同样的情况。例如,如果你有一个类A,你应该调用类C的方法来完成某个函数。但是C不让打电话。A-不能调用C的方法,直接在A和C中创建一个B代理,C让B访问。甲参观乙参观丙.

原始访问关系

通过代理的访问关系

什么是代理模式

百度百科

代理模式是指为其他对象提供代理,以控制对该对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,代理对象可以充当客户端类和目标对象之间的中介。

换句话说,代理对象用于在不修改目标对象的情况下加强主要业务逻辑。客户端类真正想访问的对象是目标对象,但客户端类真正能访问的对象是代理对象。客户端对目标对象的访问是通过访问代理对象来实现的。

是的。当然,代理类和目标类应该实现相同的接口。

实现代理的方式

静态代理

静态代理是指程序运行前代理类为已经定义好.java 源文件,与目标类的关系在程序运行前就已经确立不同。在程序运行之前,代理类已经被编译成一个. class文件。

以静态代理为例。

需求:用户需要购买u盘,u盘厂商不接受单独零散购买。厂家规定一次购买至少1000个u盘,用户可以通过淘宝代理商或者微信商家购买。对于淘宝上的商品,微商是u盘厂的代理商,他们代理u盘的销售。

服务。用户-代理商(淘宝、微信商家)-U盘厂商(金士顿、三迪等不同厂商)

1、定义业务接口

定义业务接口UsbSell(目标接口),包含抽象方法sell(int amout);卖出是目标方法。

公共接口UsbSell {

/**

*表示功能,制造商和商家必须完成该功能。

* @param金额

* @返回

*/

float sell USB(int amount);

}

2、定义接口的实现类

目标UsbKingFactory Kingston USB闪存盘,实现接口。

导入school . x UAT . service . USB sell;

公共类UsbKingFactory实现UsbSell {

@覆盖

/**

*定义金士顿制造商的销售价格。

*/

公共浮动销售Usb(内部账户){

返回75.0f

}

}

3、定义代理

淘宝是代理类,给厂商卖u盘。

导入school . x UAT . factory . usbkingfactory;

导入school . x UAT . service . USB sell;

公共类淘宝实现UsbSell {

//声明哪家厂商是商家的代理。

private UsbSell factory=new usbking factory();

@覆盖

/**

*实现出售u盘的功能。

*/

公共浮动销售Usb(内部账户){

浮动价格=factory . sell USB(account);

//代理增强功能

价格=25;

退货价格;

}

}

魏也是一家代理销售u盘的厂家。

导入school . x UAT . factory . usbkingfactory;

导入school . x UAT . service . USB sell;

公共类尚维实现UsbSell {

//声明哪家厂商是商家的代理。

private UsbSell factory=new usbking factory();

@覆盖

公共浮动sellUsb(int amount) {

浮动价格=factory.sellUsb(金额);

//代理增强功能

价格=15;

退货价格;

}

}

4、客户端调用者,购买商品类

客户可以通过淘宝和尚维代理商购买u盘。

导入school . xau at . business . Taobao;

导入school . xau at . business . weishang;

公共类ShopMain {

公共静态void main(String[] args) {

淘宝淘宝=新淘宝();

浮动价格=Taobao . sell USB(1);

System.out.println(价格);

尚维尚维=新尚维();

float price 2=weishang . sell USB(1);

system . out . println(price 2);

}

}

根据以上过程,分析静态代理的优缺点

优点:实现简单,容易理解。

缺点:

代码复杂,难于管理

代理类和目标类实现同一个接口,每个代理都需要实现目标类的方法,这就导致了大量的代码重复。如果一个方法被添加到接口中,那么除了所有目标类之外,所有代理类都需要实现这个方法。这增加了代码维护的复杂性。

代理类依赖目标类,代理类过多

如果您想要服务于多种类型,代理只服务于一种类型的目标类。需要对每个目标类进行代理,但是在程序规模稍大的情况下,静态代理无法胜任,代理类太多。

动态代理

动态代理是指JVM在程序运行时根据反射机制动态生成的代理类对象。动态代理不需要定义。代理类的java源文件。

实际上,动态代理就是在jdk运行过程中动态创建类字节码并加载到JVM中。

实现动态代理有两种常见的方法:使用 JDK 动态代理(这里主要讲),和使用 CGLIB 动态代理

CGLIB代理

CGLIB(代码生成库)是一个开源项目。是一个功能强大、高性能、高质量的代码生成类库,可以在运行时扩展Java类,实现Java接口。它被很多AOP框架广泛使用,比如Spring AOP。使用JDK

Proxy实现proxy,要求目标类和代理类实现同一个接口。如果目标类没有接口,它就不能以这种方式实现。然而,对于没有接口的类,要为它们创建一个动态代理,应该使用CGLIB。CGLIB代理的生成原理是生成目标类的子类,而

子类得到了增强,这个子类对象就是代理对象。因此,使用CGLIB生成动态代理,要求目标类必须能够被继承,即不能是final类。Cglib常用于框架中,如Spring、Hibernate等。Cglib的代理效率高于Jdk。正确

它不用于cglib的一般开发。只是做个理解。

JDK代理

基于Java反射机制实现了Jdk动态代理。使用jdk中的接口和类实现代理对象的动态创建。Jdk的动态性要求目标对象必须实现接口,这是java设计的要求。从jdk1.3开始,java语言通过java.lang.reflect包提供了三个类。

支持代理模式Proxy, Method InovcationHandler

InvocationHandler接口

调用处理程序接口称为调用处理程序,负责调用目标方法并增强其功能。通过对象执行接口中方法的替换,方法将被分配给InvocationHandler的实现类,实现类中的I将被执行。

Nvke()方法,我们需要在invoke()方法中编写功能代理。

invoke方法可以拦截对目标方法的调用。这里的功能得到了增强。Java的动态代理是基于反射机制的。实现InvocationHandler接口的类用于增强目标类的主要业务逻辑。这个接口中有一个方法invoke(),专门添加了

这种方法定义了强代码逻辑。当通过代理对象执行接口中的方法时,会自动调用invoke()方法。

invoke()方法的介绍如下:

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

proxy:代表生成的代理对象

method:代表目标方法

args:代表目标方法的参数

第一个参数proxy由jdk在运行时分配,并直接在方法中使用。后面介绍第二个参数,第三个参数是方法执行的参数。这三个参数由jdk在运行时分配,不需要程序员给出。

Method类

invoke()方法的第二个参数是方法类对象,它有一个名为invoke()的方法,可以调用目标方法。这两个invoke()方法虽然名称相同,但并不相关。

公共对象调用(对象对象,对象.参数)

Obj:表示目标对象

Args:指示目标方法参数,这是它上面的invoke方法的第三个参数。

方法用于调用obj对象所属类的方法,该方法由其调用方方法对象决定。

在代码中,一般的写法是

method.invoke(target,args);

其中method是上一层的invoke方法的第二个参数。这样就可以调用目标类的目标方法。

Proxy类

通过JDK的java.lang.reflect.Proxy类,动态代理会由它的静态方法newProxyInstance()根据目标对象、业务接口、调用处理器自动生成。

公共静态new proxy instance(Class loader loader,Class?[]接口,InvocationHandler处理程序)

Loader:目标类的类加载器,可以通过目标对象的反射获得。

Interfaces:由目标类实现的接口数组,可以通过目标对象的反射获得。

处理程序:调用处理器。

jdk动态代理的实现步骤

Jdk动态代理是代理模式的实现,只能代理接口。

实施步骤

1、新建一个接口,作为目标接口

2、为接口创建一个实现类,是目标类

3、创建类实现 java.lang.reflect.InvocationHandler 接口,调用目标方法并增加其他功能代码

4、创建动态代理对象,使用 Proxy.newProxyInstance()方法,并把返回值强制转为接口类型。

举个例子

1.创建一个目标接口并定义其功能。

2.为接口创建一个实现类。

以上两个步骤与静态代理相同。

3.创建InvocationHandler接口的实现类,调用目标方法,添加其他代码函数。

导入Java . lang . reflect . invocation handler;

导入Java . lang . reflect . method;

公共类MySellHandler实现InvocationHandler {

//目标对象

私有对象target=null

public MySellHandler(对象目标){

this.target=target

}

@覆盖

/**

*实现InvocationHandler接口的实现类,完成invoke方法中代理类的功能。

*-调用目标方法

*-功能增强

*/

公共对象调用(对象代理、方法方法、对象[]参数)抛出Throwable {

对象结果=null

result=method.invoke(target,args);

//功能增强

//这里为了简化,我们把功能增强定义为加价25元。

如果(结果!=null){

浮动价格=(浮动)结果;

价格=价格25;

结果=价格;

}

返回结果;

}

}

这里的目标对象相当于静态代理中的淘宝和尚维。

4.模拟客户购买u盘,使用proxy.newProxyInstance创建代理对象,返回值为目标接口类型。

导入school . x UAT . factory . usbkingfactory;

导入school . x UAT . handler . my sell handler;

导入school . x UAT . service . USB sell;

导入Java . lang . reflect . invocation handler;

导入Java . lang . reflect . proxy;

公共类MainShop {

公共静态void main(String[] args)引发异常{

//创建目标对象

Class c=UsbKingFactory.class

object obj=c . new instance();

//获取目标类的类加载器

class loader loader=usbking factory . class . getclass loader();

//获取目标类实现的接口数组

班级?[]interfaces=obj.getClass()。get interfaces();

//创建InvocationHandler对象

invocation handler=new mysell handler(obj);

//创建代理对象

UsbSell proxy=(UsbSell)proxy . newproxyinstance(loader,interfaces,handler);

//通过此代理执行方法

浮动价格=proxy . sell(1);

System.out.println(价格);

}

}

静态代理

动态代理

UML图

总结

本文到此为止。希望能帮到你,也希望你能多关注我们的更多内容!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: