java动态代理有几种方式,java的动态代理机制详解
这篇文章给你带来了一些关于java的知识。动态代理意味着代理类和目标类之间的关系是在程序运行时确定的。客户端通过代理类调用目标对象的方法是在程序运行时动态创建目标类的代理对象。下面将通过一个案例详细讲解Java动态代理的原理和实现,希望对大家有所帮助。
如何解决写爬虫IP受阻的问题?立即使用。
相信‘代理人’这个词大家都很熟悉。简单来说就是代厂家卖货,代厂家卖货,客户找代理商进货。也就是说:1)客户和厂家的关系是隐形的,客户不知道厂家背后是谁。2)代理商可以“定位”客户,更精准地销售给需要的客户群体。
代理模式
代理模式:为其他对象提供代理来控制对该对象的访问,即创建一个代理对象作为客户端和目标对象之间的中介,主要目的是保护或增强目标对象。
通过使用代理模式,通常有以下两个优点:
\1)您可以隐藏代理类的实现。
\2)可以实现客户端和主体类的解耦,不需要修改主体类的代码就可以做一些额外的处理。
静态代理
所谓动态代理,就是通过声明一个显式的代理类来访问源对象。一个代理只能服务一种产品。当有n个产品时,就需要n个代理,不利于业务的发展。
比如我们有两个接口,鼠标和键盘,每个接口都有一个实现类。
实现中的代码如下:
公共类LogitechMouse实现鼠标{
@覆盖
public void sell() {
System.out.println(出售罗技鼠标);
}
}
公共类HHKBKeyboard实现键盘{
@覆盖
public void sell() {
System.out.println(卖HHKB键盘);
}
}现在我们要做的就是让代理商在打电话之前输出一句售前理解句,打电话之后输出一句售后服务句。
然后我们只需要写两个代理类,MouseProxy和KeyboardProxy。
公共类MouseProxy实现鼠标{
私鼠鼠;
公共鼠标代理(鼠标鼠标){
this.mouse=mouse
}
@覆盖
public void sell() {
System.out.println(“售前知识”);
mouse . sell();
System.out.println(“售后服务”);
}
}
公共类KeyboardProxy实现键盘{
私人键盘键盘;
公共键盘代理(键盘键盘){
this.keyboard=键盘;
}
@覆盖
public void sell() {
System.out.println(“售前知识”);
keyboard.sell()。
System.out.println(“售后服务”);
}
}最后执行的是:
公共类测试{
公共静态void main(String[] args) {
mouse logitechMouse=new logitechMouse();
mouse proxy mouse proxy=new mouse proxy(logitechMouse);
mouse proxy . sell();
keyboard hhkbKeyboard=new hhkbKeyboard();
keyboard proxy keyboard proxy=new keyboard proxy(hhkbKeyboard);
keyboard proxy . sell();
}
}静态代理的代码非常简单易懂。这种模式虽然好,但也有明显的缺点:
将会有大量冗余的代理类。这里只有两个接口。如果有n个接口,那么就需要定义n个代理类。维护起来并不容易。一旦接口改变,代理类和代理类都必须改变。那么你可以使用动态代理来解决这个问题。
动态代理
proxy类在程序运行时创建代理的方式称为动态代理,也就是说proxy类不是在java代码中定义的,而是在运行时动态生成的。
JDK动态代理
JDK从版本1.3开始就支持动态代理类的创建。只有两个核心类:java.lang.reflect.Proxy和Java . lang . reflect . invocation handler。
还是上面的例子,JDK的动态代理如下:
公共类JDKProxy实现InvocationHandler {
私有对象Object;
public JDKProxy(Object object) {
this.object=对象
}
@覆盖
公共对象调用(对象代理、方法方法、对象[]参数)抛出可投掷的
System.out.println(售前了解);
对象调用=方法调用(对象,参数);
System.out.println(售后服务);
返回调用;
}
}当我们调用代理类对象的方法时,这个"调用"会转送到引起方法中,
代理类对象作为代理人参数传入,
参数方法标识了我们具体调用的是代理类的哪个方法,
一个参数名为这个方法的参数。
这样一来,我们对代理类中的所有方法的调用都会变为对引起的调用,这样我们可以在引起方法中添加统一的处理逻辑(也可以根据方法参数对不同的代理类方法做不同的处理)。因此我们可以在中介类的引起方法中实现输出售前了解,再调用被代理类的方法,再输出售后服务。
执行代码
公共类测试{
公共静态void main(String[] args) {
mouse logitechMouse=new logitechMouse();
JDK代理JDK代理=新JDK代理(logitechMouse);
Mouse Mouse=(Mouse)代理。JDK代理。获取类().getClassLoader(),new Class[]{Mouse.class},JDK代理);
老鼠。sell();
HHKBKeyboard HHKBKeyboard=new HHKBKeyboard();
JDK代理JDK代理1=新JDK代理(hhkbKeyboard);
键盘Keyboard=(Keyboard)代理。newproxyinstance(JDK代理1。获取类().getClassLoader(),新类[]{Keyboard.class},JDK代理1);
keyboard.sell()。
}
}可以看到无论多少个接口,只需要一个代理类就可以了。
CGLIB动态代理
代理类:
公共类CGLIBProcy实现MethodInterceptor {
私有增强器Enhancer=新增强子();
私有对象对象;
public CGLIBProcy(Object Object){
this.object=对象
}
公共对象getProxy(){
//设置需要创建子类的类
增强剂。设置超类(对象。getclass());
增强剂。设置回调(this);
//创建代理对象
回归增强器。create();
}
//o: cglib动态生成的代理类的实例
//方法:实体类所调用的都被代理的方法的引用
//对象参数列表
//methodProxy:生成的代理类对方法的代理引用
@覆盖
公共对象拦截(对象哦,方法方法,对象[]对象,方法代理方法代理)抛出可投掷的
System.out.println(售前了解);
对象调用=方法调用(对象,对象);
System.out.println(售后处理);
返回调用;
}
}执行代码:
公共类测试{
公共静态void main(String[] args) {
mouse logitechMouse=new logitechMouse();
CGLIBProcy cglibProcy=新CGLIBProcy(logitechMouse);
Mouse proxy=(Mouse)cglibprocy。get proxy();
代理。sell();
cglibProcy=new cglibProcy(new HHKBKeyboard());
Keyboard Keyboard=(Keyboard)cglibprocy。get proxy();
keyboard.sell()。
}
}
JDK代理与CGLIB代理的区别
JDK动态代理实现接口,CGLIB动态继承思想爪哇岛开发工具包动态代理(目标对象存在接口时)执行效率高于CIGLIB如果对象有接口实现,选择爪哇岛开发工具包代理,如果没有接口实现选择CGILB代理推荐学习: 《java视频教程》 以上就是完全掌握爪哇动态代理的详细内容,更多请关注我们其它相关文章!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。