JDK动态代理具体解释
首先说一下动态代理和静态代理的差别:
静态代理:是预先写好或由特定工具自己主动生成的代码。再对其编译。在程序执行前。代理类的.class文件就已经存在了。
动态代理:代理是在程序执行时,运用反射机制动态创建而成的,程序执行之前,代理是不存在的。
Java的静态代理最简单的场景,一个接口,一个实现类,一个代理类就能够搞定。这个代理类持有接口实现类的引用,这样便能够实现托付对象的增强了。
Java的动态代理主要有两种。JDK动态代理和cglib动态代理
当中JDK动态代理,主要利用了接口InvocationHandler,还有Proxy类。
InvocationHandler接口:
public interface InvocationHandler {
public Object invoke(Object proxy,Method method,Object[] args) throws Throwable;
}
參数说明:
Object proxy:指代理对象。
Method method:要调用的方法
Object[] args:方法调用时所须要的參数
Proxy类:
Proxy类是专门完毕代理的操作类,能够通过此类为一个或多个接口的实现类动态地生成代理类,此类提供了例如以下的操作方法:
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException
參数说明:
ClassLoader loader:类载入器
Class<?
>[] interfaces:得到所有的接口
InvocationHandler h:得到InvocationHandler接口的子类实例
动态代理类的字节码在程序执行时由Java反射机制动态生成。无需程序猿手工编写它的源码。动态代理类不仅简化了编程工作,并且提高了软件系统的可扩展性。由于Java 反射机制能够生成随意类型的动态代理类。java.lang.reflect 包中的Proxy类和InvocationHandler 接口提供了生成动态代理类的能力。 以下看一下我写的一个小样例~
package go.derek; interface Istudy
{
public void study(String words);
}
上面的接口定义了一个方法。
以下是这个接口的实现类
package go.derek; class StudyImpl implements Istudy
{
public void study(String words){
System.out.println(words);
}
}
以下看一下代理类的代码
package go.derek; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
class StudyProxy implements InvocationHandler
{
private Object target;
public Object bind(Object target){
this.target=target;
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
} public Object invoke(Object proxy,Method method,Object[] args) throws Throwable{
System.out.println("start");
Object obj=method.invoke(target,args);
System.out.println("rest");
return obj;
} }
以下是測试类的代码
package go.derek; class ProxyTest
{
public static void main(String[] args)
{
StudyProxy sp=new StudyProxy();
Istudy derek=(Istudy)sp.bind(new StudyImpl());
derek.study("I'm derek");
}
}
以下是输出结果:
start
I'm derek
rest
我们能够看出,代理类确实给托付类实现了增强,不能忽视的是代理类要持有托付类对象的引用。
JDK的动态代理机制仅仅能代理实现了接口的类,而不能实现接口的类就不能实现JDK的动态代理。cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖当中方法实现增强,但由于採用的是继承。所以不能对final修饰的类进行代理。
JDK动态代理具体解释的更多相关文章
- JDK动态代理
一.基本概念 1.什么是代理? 在阐述JDK动态代理之前,我们很有必要先来弄明白代理的概念.代理这个词本身并不是计算机专用术语,它是生活中一个常用的概念.这里引用维基百科上的一句话对代理进行定义: A ...
- 【原创】JDK动态代理,此次之后,永生难忘。
动态代理,这个词在Java的世界里面经常被提起,尤其是对于部分(这里强调“部分”二字,因为有做了一两年就成大神的,实力强的令人发指,这类人无疑是非常懂动态代理这点小伎俩的)做了一两年新人来说,总是摸不 ...
- MyBatis Mapper 接口如何通过JDK动态代理来包装SqlSession 源码分析
我们以往使用ibatis或者mybatis 都是以这种方式调用XML当中定义的CRUD标签来执行SQL 比如这样 <?xml version="1.0" encoding=& ...
- JDK 动态代理分析
Java的代理有两种:静态代理和动态代理,动态代理又分为 基于jdk的动态代理 和 基于cglib的动态代理 ,两者都是通过动态生成代理类的方法实现的,但是基于jdk的动态代理需要委托类实现接口,基于 ...
- JDK动态代理[4]----ProxyGenerator生成代理类的字节码文件解析
通过前面几篇的分析,我们知道代理类是通过Proxy类的ProxyClassFactory工厂生成的,这个工厂类会去调用ProxyGenerator类的generateProxyClass()方法来生成 ...
- Java JDK动态代理解析
动态代理虽不常自己实现,但在Spring或MyBatis中都有重要应用.动态代理的意义在于生成一个占位(又称代理对象),来代理真实对象,从而控制真实对象的访问.Spring常JDK和CGLIB动态代理 ...
- JDK动态代理给Spring事务埋下的坑!
一.场景分析 最近做项目遇到了一个很奇怪的问题,大致的业务场景是这样的:我们首先设定两个事务,事务parent和事务child,在Controller里边同时调用这两个方法,示例代码如下: 1.场景A ...
- 转:jdk动态代理实现
原文链接: jdk动态代理 注:文章中用常用的流程实现 动态代理,流程逻辑比较清晰.文章后面对 “为什么要使用接口” 原理分析还未细看. jdk的动态代理为什么用接口,内部是什么原理呢?看了几篇文章貌 ...
- (转)面试必备技能:JDK动态代理给Spring事务埋下的坑!
一.场景分析 最近做项目遇到了一个很奇怪的问题,大致的业务场景是这样的:我们首先设定两个事务,事务parent和事务child,在Controller里边同时调用这两个方法,示例代码如下: 1.场景A ...
随机推荐
- STL源码剖析(容器适配器)
在STL中,有一类容器完全以底部容器为基础进行实现,这类容器归类为container adapter. priority_queue priority_queue默认使用vector为基础,加上hea ...
- 【FinancialKnowledge】拨备
一句话: 银行拨备就是银行贷款损失减值准备的俗称,其相当于为承担风险和损失的金融资产计提的准备金 通俗易懂的解释见:https://wallstreetcn.com/articles/3307725
- 动态创建 Log4net 实例
动态创建log4net 实例 根据业务类型,动态的创建日志实例,将日志写到不同目录.常见的配置文件中统一配置,不能满足需求. 引用log4net nuget安装命令: Install-Package ...
- 电子商务(电销)平台中订单模块(Order)数据库设计明细(转载)
电子商务(电销)平台中订单模块(Order)数据库设计明细 以下是自己在电子商务系统设计中的订单模块的数据库设计经验总结,而今发表出来一起分享,如有不当,欢迎跟帖讨论~ 订单表 (order)|-- ...
- Paper Reading 1 - Playing Atari with Deep Reinforcement Learning
来源:NIPS 2013 作者:DeepMind 理解基础: 增强学习基本知识 深度学习 特别是卷积神经网络的基本知识 创新点:第一个将深度学习模型与增强学习结合在一起从而成功地直接从高维的输入学习控 ...
- oblique perspective projection
参考: https://en.wikibooks.org/wiki/GLSL_Programming/Vertex_Transformations <3D游戏与计算机图形学中的数学方法>E ...
- 转:python之如何在某文件中调用其他文件内的函数
假设名为A.py的文件需要调用B.py文件内的C(x,y)函数 情形1:在同一目录下, (1) import B if __name__ == "__main__": B.C(x, ...
- nginx 查看访问 IP 并封禁 IP 详解
1.查找服务器所有访问者ip方法: awk '{print $1}' nginx_access.log |sort |uniq -c|sort -n nginx.access.log 为nginx访问 ...
- JS高程3:Ajax与Comet-进度事件、跨源资源共享
有以下 6 个进度事件 loadstart:在接收到响应数据的第一个字节时触发. progress:在接收响应期间持续不断地触发. error:在请求发生错误时触发. abort:在因 ...
- 【Objective-C】05-第一个OC的类
OC是一门面向对象的语言,因此它也有类.对象.静态\动态方法.成员变量的概念.这讲就来创建第一个OC的类. 一.语法简介 1.类 在Java中,我们用1个.java文件就可以描述清楚一个类:在OC中, ...