- 浏览: 596395 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (213)
- jdk (40)
- J2EE (8)
- JavaScript (16)
- spring (1)
- 正则 (10)
- ORACLE (18)
- CSS (1)
- 生活学习 (14)
- XML (3)
- Linux (11)
- 项目架设 (12)
- Junit (1)
- Derby (3)
- JMX (5)
- 版本控制 (4)
- PowerDesigner (1)
- 加密解密 (1)
- android (4)
- Eclipse (4)
- Hibernate (6)
- Tomcat (4)
- JasperReport&iReport (1)
- SqlServer (6)
- C++ (3)
- 系统架构涉及名词解释 (5)
- Hadoop (8)
- windows (2)
- SOA (1)
- 有趣的Google (1)
- 编程语言 (0)
- 数据结构与算法 (1)
- nodejs (1)
- 一些测试整理备份在这里吧 (0)
- 性能 (3)
- Drill (5)
- 学习 (1)
最新评论
一.相关类及其方法:
java.lang.reflect.Proxy,
Proxy 提供用于创建动态代理类和实例的静态方法.
newProxyInstance()
返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序
(详见api文档)
java.lang.reflect.InvocationHandler,
InvocationHandler 是代理实例的调用处理程序 实现的接口。
invoke()
在代理实例上处理方法调用并返回结果。在与方法关联的代理实例上调用方法时,将在调用处理程序上调用此方法。
(详见api文档)
二.源代码:
被代理对象的接口及实现类:
业务代理类:
客户端类:
三.执行结果:
do something before method
*******modify()方法被调用
do something after method
四.机制分析:
Proxy.(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)做了以下几件事.
(1)根据参数loader和interfaces调用方法 getProxyClass(loader, interfaces)创建代理类$Proxy.
$Proxy0类实现了interfaces的接口,并继承了Proxy类.
(2)实例化$Proxy0并在构造方法中把BusinessHandler传过去,接着$Proxy0调用父类Proxy的构造器,为h赋值,如下:
下面是本例的$Proxy0类的源码(好不容易才把它提出来,改了JRE源码,打印出字节码,把字节码保存为class文件,并反编译class文件):
接着把得到的$Proxy0实例强制转换成Manager.
当执行managerProxy.modify()方法时,就调用了$Proxy0类中的modify()方法.
在modify方法中,调用父类Proxy中的h的invoke()方法.
即InvocationHandler.invoke();
System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D:/cglib");
net.sf.cglib.core.DebuggingClassWriter
java.lang.reflect.Proxy,
Proxy 提供用于创建动态代理类和实例的静态方法.
newProxyInstance()
返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序
(详见api文档)
java.lang.reflect.InvocationHandler,
InvocationHandler 是代理实例的调用处理程序 实现的接口。
invoke()
在代理实例上处理方法调用并返回结果。在与方法关联的代理实例上调用方法时,将在调用处理程序上调用此方法。
(详见api文档)
二.源代码:
被代理对象的接口及实现类:
package com.ml.test; public interface Manager { public void modify(); } package com.ml.test; public class ManagerImpl implements Manager { @Override public void modify() { System.out.println("*******modify()方法被调用"); } }
业务代理类:
package com.ml.test; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class BusinessHandler implements InvocationHandler { private Object object = null; public BusinessHandler(Object object) { this.object = object; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("do something before method"); Object ret = method.invoke(this.object, args); System.out.println("do something after method"); return ret; } }
客户端类:
package com.ml.test; import java.lang.reflect.Proxy; public class Client { public static void main(String[] args) { // 元对象(被代理对象) ManagerImpl managerImpl = new ManagerImpl(); // 业务代理类 BusinessHandler securityHandler = new BusinessHandler(managerImpl); // 获得代理类($Proxy0 extends Proxy implements Manager)的实例. Manager managerProxy = (Manager) Proxy.newProxyInstance(managerImpl .getClass().getClassLoader(), managerImpl.getClass() .getInterfaces(), securityHandler); managerProxy.modify(); } }
三.执行结果:
do something before method
*******modify()方法被调用
do something after method
四.机制分析:
Proxy.(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)做了以下几件事.
(1)根据参数loader和interfaces调用方法 getProxyClass(loader, interfaces)创建代理类$Proxy.
$Proxy0类实现了interfaces的接口,并继承了Proxy类.
(2)实例化$Proxy0并在构造方法中把BusinessHandler传过去,接着$Proxy0调用父类Proxy的构造器,为h赋值,如下:
class Proxy{ InvocationHandler h=null; protected Proxy(InvocationHandler h) { this.h = h; } ... }
下面是本例的$Proxy0类的源码(好不容易才把它提出来,改了JRE源码,打印出字节码,把字节码保存为class文件,并反编译class文件):
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.lang.reflect.UndeclaredThrowableException; public final class $Proxy0 extends Proxy implements Manager { private static Method m1; private static Method m0; private static Method m3; private static Method m2; static { try { m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") }); m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]); m3 = Class.forName("com.ml.test.Manager").getMethod("modify", new Class[0]); m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]); } catch (NoSuchMethodException nosuchmethodexception) { throw new NoSuchMethodError(nosuchmethodexception.getMessage()); } catch (ClassNotFoundException classnotfoundexception) { throw new NoClassDefFoundError(classnotfoundexception.getMessage()); } } public $Proxy0(InvocationHandler invocationhandler) { super(invocationhandler); } @Override public final boolean equals(Object obj) { try { return ((Boolean) super.h.invoke(this, m1, new Object[] { obj })) .booleanValue(); } catch (Throwable throwable) { throw new UndeclaredThrowableException(throwable); } } @Override public final int hashCode() { try { return ((Integer) super.h.invoke(this, m0, null)).intValue(); } catch (Throwable throwable) { throw new UndeclaredThrowableException(throwable); } } public final void modify() { try { super.h.invoke(this, m3, null); return; } catch (Error e) { } catch (Throwable throwable) { throw new UndeclaredThrowableException(throwable); } } @Override public final String toString() { try { return (String) super.h.invoke(this, m2, null); } catch (Throwable throwable) { throw new UndeclaredThrowableException(throwable); } } }
接着把得到的$Proxy0实例强制转换成Manager.
当执行managerProxy.modify()方法时,就调用了$Proxy0类中的modify()方法.
在modify方法中,调用父类Proxy中的h的invoke()方法.
即InvocationHandler.invoke();
评论
2 楼
ldbjakyo
2014-01-13
abc08010051 写道
请楼主详细说明如何获得生成的动态代理类的源码
System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D:/cglib");
net.sf.cglib.core.DebuggingClassWriter
1 楼
abc08010051
2013-10-14
请楼主详细说明如何获得生成的动态代理类的源码
发表评论
-
关于饿汉式单例首次初始化失败后,可以再次尝试?
2012-07-11 15:14 1266思考一个问题,以下代码是一个简单的饿汉式单例代码,显然在第一次 ... -
由ApacheCommon-BeanUtils1.8.3发现的Java HotSpot(TM)的Bug
2012-07-03 15:42 1608由ApacheCommon-BeanUtils1.8.3发现的 ... -
JVM垃圾回收
2012-04-19 13:02 3527一、JVM内存模型及垃圾收集算法 1.根据Java虚 ... -
Java构建HashCode相同字符串算法
2012-01-10 15:05 5567import java.math.BigDecimal; ... -
线程全部结束与集合点
2011-11-12 16:26 1256final int size = 50; fin ... -
ddddddddd
2011-11-12 16:21 1258dddddddddd -
ccccccc
2011-11-12 16:20 2004ccccccccccc -
bbbbbb
2011-11-12 16:19 1800bbbbb -
Aaaaa
2011-11-12 16:19 940aaaaaaaa -
备忘链接
2011-08-16 18:25 958翻译,随便写了写,备忘一下 URLConnection co ... -
jvisualvm监听JVM
2011-08-05 10:14 1210配置好 set JAVA_OPTS=%JAVA_OPTS ... -
JVM 调优 技巧
2011-08-02 15:59 12661.升级 JVM 版本。如果能使用64-bit,使用64-bi ... -
JVM垃圾回收策略
2011-08-02 14:59 1066为什么要分代 分代的垃圾回收策略,是基于这样一个事实:不 ... -
Java GC
2011-08-02 13:38 1059调整JVM GC(Garbage Collection),可 ... -
Java的弱引用(Weak Reference)
2011-05-18 16:07 1253要理解弱引用,首先要 ... -
使用classloader动态加载Class
2011-05-17 14:25 970http://www.javaworld.com/javawo ... -
查看class文件信息
2011-05-16 14:15 1708看了第6章的java class文件这一部分,我觉得对clas ... -
.class文件格式--java字节码文件的格式
2011-05-14 23:07 25471 . 目的 Java 虚拟机识别的 class 文件格式包含 ... -
Calendar
2011-03-30 14:13 1061/**获得参数月份的一号及其下一个月的一号*/ priva ... -
Bad version number in .class file
2011-03-04 15:08 1343java.lang.UnsupportedClassVersi ...
相关推荐
### 关于JDK动态代理的源码剖析 #### 一、引言 在Java开发过程中,动态代理技术是一项非常实用的技术,它可以帮助我们实现在不修改原有代码的基础上为方法增加额外的功能,比如日志记录、权限校验等。本文将深入...
JDK动态代理,全称为Java Dynamic Proxy,是Java标准库提供的一种强大且灵活的机制,允许我们在运行时创建代理类来实现指定的接口。这种机制主要用于实现AOP(面向切面编程)或为已有接口提供额外的功能,如日志、...
1. **Java.lang.reflect.Proxy**:这是JDK动态代理的关键类,它提供了创建动态代理对象的工厂方法`newProxyInstance()`。这个方法接收三个参数:`ClassLoader`用于加载代理类,`Interface[]`表示代理对象需要实现的...
JDK动态代理的核心API包括`java.lang.reflect.Proxy`和`java.lang.reflect.InvocationHandler`。 - **`java.lang.reflect.Proxy`**:提供了创建动态代理类和实例的方法。通过`newProxyInstance`方法,传入...
首先,JDK动态代理主要依赖于java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口。Proxy类用于创建一个代理对象,而InvocationHandler接口则定义了处理代理对象调用方法的逻辑。当调用代理对象的...
Proxy 类是 JDK 中的动态代理类,是动态代理的核心类,其作用类似于代理模式中的代理。Proxy 类中包含的全是静态的方法和成员变量,这是一个纯粹的工具类,因此其源代码中含有一个私有的构造器,在某种意义上可以看...
在Java中,动态代理是通过java.lang.reflect包下的两个类实现的:Proxy和InvocationHandler。Proxy类用于创建代理对象,而InvocationHandler接口则定义了处理代理对象方法调用的逻辑。 1. **Proxy类**: - Proxy类...
JDK动态代理主要依赖于`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口。Proxy类是生成代理对象的工厂,而InvocationHandler接口定义了调用处理程序的接口,用于处理对代理对象的方法调用...
1. **Proxy类**:这是JDK动态代理的核心类,它提供了`newProxyInstance()`静态方法,用于创建代理对象。 2. **InvocationHandler接口**:每个代理对象都关联一个`InvocationHandler`实例。当代理对象的方法被调用时...
首先,JDK动态代理基于Java的反射机制,通过`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口来实现。Proxy类用于创建一个代理对象,而InvocationHandler接口定义了一个方法`invoke()`,该...
首先,JDK动态代理是Java内置的一种机制,它依赖于`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口。`Proxy`类用于创建代理对象,而`InvocationHandler`接口定义了处理代理对象方法调用的...
- `InvocationHandler`是JDK动态代理的核心,它定义了一个invoke()方法,该方法会在代理类调用目标方法时被触发。 - 我们需要实现`InvocationHandler`接口,重写invoke()方法,当调用代理对象的方法时,实际执行的...
JDK动态代理主要通过`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口来实现。Proxy类用于创建一个代理对象,而InvocationHandler接口定义了处理代理对象的方法调用的逻辑。当通过Proxy创建...
JDK 动态代理主要涉及到 java.lang.reflect 包中的两个类:Proxy 和 InvocationHandler。 InvocationHandler 是一个接口,可以通过实现该接口定义横切逻辑,并通过反射机制调用目标类的代码,动态将横切逻辑和业务...
4. **模拟内部实现**: 要模拟JDK动态代理的内部实现,我们可以自己创建一个类来代替`Proxy`,并一个接口来代替`InvocationHandler`。这样,我们就能自由控制代理的创建过程和方法调用的行为,从而更好地理解动态代理...
标题 "JDK动态代理在EJB3(包括WebService)中的应用" 暗示了本文将探讨Java开发中的一种重要技术——JDK动态代理,以及它如何在企业级JavaBean (EJB) 3.x版本及其相关的Web服务实现中发挥作用。EJB3是Java EE平台的...
Java JDK提供了`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口,它们是实现动态代理的关键组件。`Proxy`类用于创建代理对象,而`InvocationHandler`接口定义了一个方法,用于处理代理对象...
Spring AOP中的JDK动态代理与上述示例类似,只是Spring会自动处理代理对象的创建和`InvocationHandler`的设置。Spring通过`DefaultAopProxyFactory`和`JdkDynamicAopProxy`类来实现这一过程。在配置了AOP代理后,当...
JDK动态代理是Java内置的一种机制,依赖于`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口。以下是JDK动态代理的基本工作原理: 1. **InvocationHandler接口**:这是处理代理对象方法调用...
在这个“jdk动态代理 + 拦截器实现小例”中,我们将探讨如何利用Java的InvocationHandler接口和Proxy类来实现拦截器模式,以实现灵活的代码扩展和日志记录、性能监控等需求。 首先,让我们理解什么是动态代理。在...