Java动态代理

作者: 生活就是小说 | 来源:发表于2020-09-06 14:42 被阅读0次

先看再点赞,给自己一点思考的时间,如果对自己有帮助,微信搜索【程序职场】关注这个执着的职场程序员。
价值:Java技能,面试经验指导,简历优化,职场规划指导,技能提升方法,讲不完的职场故事,个人成长经验。

01

概念

动态代理是设计模式当中代理模式的一种。

主要用来做方法的增强,让你可以在不修改源码的情况下,增强一些方法,在方法执行前后做任何你想做的事情,因为在InvocationHandler的invoke方法中,你可以直接获取正在调用方法对应的Method对象,具体应用的话。

比如可以添加调用日志,做事务控制等。

随让上面说了很多的有点,但是也是存在不足的。

诚然,Proxy已经设计得非常优美,但是还是有一点点小小的遗憾之处,那就是它始终无法摆脱仅支持interface代理的桎梏,因为它的设计注定了这个遗憾。

回想一下那些动态生成的代理类的继承关系图,它们已经注定有一个共同的父类叫Proxy

Java的继承机制注定了这些动态代理类们无法实现对class的动态代理,原因是多继承在Java中本质上就行不通。

有很多条理由,人们可以否定对 class代理的必要性,但是同样有一些理由,相信支持class动态代理会更美好。

接口和类的划分,本就不是很明显,只是到了Java中才变得如此的细化。

如果只从方法的声明及是否被定义来考量,有一种两者的混合体,它的名字叫抽象类。实现对抽象类的动态代理,相信也有其内在的价值。此外,还有一些历史遗留的类,它们将因为没有实现任何接口而从此与动态代理永世无缘。

如此种种,不得不说是一个小小的遗憾。但是,不完美并不等于不伟大,伟大是一种本质,Java动态代理就是佐例。

Jdk动态代理之所以只能代理接口是因为代理类本身已经extends了Proxy,而java是不允许多重继承的,但是允许实现多个接口,因此才有这样的需要。

终于知道为什么说“Jdk动态代理局限于接口是因为Java只支持单继承”。

02

总结

1,JDK动态代理是基于接口的代理,其将代理接口中包括default方法在内的所有方法;

2,InvocationHandler是一个函数式接口(类似Runnable接口),其invoke方法指定方法的代理逻辑;

3,代理类的Method属性是接口中的方法对象,不是实现类的,注解加在接口方法上才能拿到;

03

使用步骤

1.通过实现InvocationHandler接口定义自己的InvocationHandler。

2.通过Proxy.getProxyClass0方法获得动态代理类。

3.通过反射机制获取动态代理类的构造方法,getConstructor(InvocationHandler.class)。

4.通过构造函数获得代理对象,并将第一步时自定义的InvocationHandler实例对象作为入参,newInstance(new Object[]{InvocationHandler})。

5.通过代理对象调用方法。

04

实战详解

1.定义需要被动态代理的接口

publicinterfaceSubject{voidsubjectRun(String param);}

2.被真正代理的类,用来处理实际业务

publicclassRealSubjectimplementsSubject{publicvoidsubjectRun(String param){System.out.println("代理对象的方法被执行了!"+param);  }}

3.定义代理类需实现InvocationHandler

publicclassProxySubjectimplementsInvocationHandler{//真正被代理的对象
private Object subject; //通过构造方法为代理对象赋值
public ProxySubject(Object subject){ 
this.subject = subject;
}
/*** @param proxy 动态生成的代理类   
* @param method 被代理的类的方法   
* @param args  调用被代理类的入参   
* @return    * @throws Throwable   
*/@Override
public Object invoke(Object proxy, Method method, Object[] args)  throws Throwable { 
Object result = null; 
System.out.println("目标对象方法执行之前对方法加强!"); 
method.invoke(subject,args); 
//subject:被代理的对象 args:调用方法的入参 
System.out.println("目标对象方法执行之前对方法加强!"); 
return result;
}
}

4.测试类

publicclassProxyRun{publicstaticvoidmain(String[] args){
//被真实代理的类,处理实际业务
Subject subject =newRealSubject();
//实现InvocationHandler的代理类
InvocationHandler h =newProxySubject(subject);
//动态生成代理类对象
Subject subjectProxy = (Subject)Proxy.newProxyInstance (h.getClass().getClassLoader(), subject.getClass().getInterfaces(),h);//调用动态生成代理类的方法subjectProxy.subjectRun("execute");
}
}

5.程序运行结果

目标对象方法执行之前对方法加强!
代理对象的方法被执行了!execute
目标对象方法执行之后对方法加强!

05

实战详解

最后给大家来一个代理模式结构图(来自网络)

我是【尔东双月】一枚执着的职场程序员,微信搜索【程序职场】关注我。别忘了三连啊,点赞、收藏、留言,随意给,我不挑。
知乎号: 程序职场
CSDN:程序职场
注:如果文章有任何问题,欢迎毫不留情地指正。

相关文章

  • Java 动态代理

    java的动态代理机制详解 JDK动态代理详解 Java核心技术点之动态代理

  • JDK动态代理详解

    JDK动态代理详解 java动态代理类 Java动态代理类位于java.lang.reflect包下,一般主要涉及...

  • Java动态代理从入门到原理再到实战

    目录 前言 什么是动态代理,和静态代理有什么区别 Java动态代理的简单使用 Java动态代理的原理解读 动态代理...

  • java反射和动态代理

    java动态代理Proxy.newProxyInstance 详解java代理机制(静态代理、动态代理)以及使用场景

  • 保存java 动态代理生成的字节码文件

    保存java 动态代理生成的字节码文件 在Java中,常用的动态代理技术有JDK的动态代理和cglib动态代理,不...

  • java动态代理(JDK和cglib)(转载自http://ww

    java动态代理(JDK和cglib) JAVA的动态代理 代理模式 代理模式是常用的java设计模式,他的特征是...

  • java基础巩固笔记(4)-代理

    标签: java Contents java基础巩固笔记(4)-代理概念动态代理创建动态类动态代理的工作原理面向切...

  • java 动态代理

    动态代理动态代理可以让我们在运行时动态生成代理类,解耦程度更高。Java 动态代理的实现主要借助于 java.la...

  • java随笔(十一)

    java动态代理源码分析,总结。java动态代理实现步骤: 通过阅读源码发现,动态生成代理对象$Proxy0,该对...

  • Java基础:反射

    反射注解动态代理相关阅读 Java基础:类加载器 Java基础:反射 Java基础:注解 Java基础:动态代理 ...

网友评论

    本文标题:Java动态代理

    本文链接:https://www.haomeiwen.com/subject/jvscektx.html