java 动态代理原理详解
来源:互联网 发布:wince软件下载 编辑:程序博客网 时间:2024/06/18 17:40
一,具体实现接口
package proxy_pattern.move_proxy_sun;
package proxy_pattern.move_proxy_sun;
public interface Ticket {
public void getTicket();
}
二、具体实现类
package proxy_pattern.move_proxy_sun;
public void getTicket();
}
二、具体实现类
package proxy_pattern.move_proxy_sun;
public class TicketImpl implements Ticket {
@Override
public void getTicket() {
System.out.println("开始买票");
public void getTicket() {
System.out.println("开始买票");
}
}
三、创建InvocationHandler实现类
package proxy_pattern.move_proxy_sun;
三、创建InvocationHandler实现类
package proxy_pattern.move_proxy_sun;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyTicket implements InvocationHandler {
public Object obj;
public Object obj;
public ProxyTicket(Object obj) {
this.obj = obj;
}
this.obj = obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(proxy.getClass().getName());
System.out.println(method.getName());
System.out.println("代理之前");
method.invoke(obj, args);
System.out.println("代理之后");
return null;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(proxy.getClass().getName());
System.out.println(method.getName());
System.out.println("代理之前");
method.invoke(obj, args);
System.out.println("代理之后");
return null;
}
}
四、主函数
Ticket obj = new TicketImpl();
InvocationHandler invocation = new ProxyTicket(obj);
四、主函数
Ticket obj = new TicketImpl();
InvocationHandler invocation = new ProxyTicket(obj);
Ticket t = (Ticket) Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), invocation);
t.getTicket();
原理说明:
通过调用 Proxy.newProxyInstance()方法,用来生成Proxy0类,这个类其实也是实现了Ticket接口的动态生成的类,当我们调用t.getTicket()方法的时候,其实我们调用的是Proxy0类里面的 getTicket()方法,这个方法的里面又开始调用了实现了InvocationHandler接口的ProxyTicket对象的public Object invoke(Object proxy, Method method, Object[] args) throws Throwable 这个方法,这个方法又调用了TicketImpl里面的getTicket()方法;
具体步骤如下:
一、调用Proxy.newProxyInstance方法
1、调用Class cl = getProxyClass(loader, interfaces);方法返回Proxy0类
getProxyClass方法如下步骤:
1,)byte[] proxyClassFile = ProxyGenerator.generateProxyClass( proxyName, interfaces);调用这个方式生成一个实现了Ticket接口的Proxy0类字节码数据,
2,) proxyClass = defineClass0(loader, proxyName,proxyClassFile, 0, proxyClassFile.length);把字节数据生成一个Class
2、生成的Proxy0的源代码如下,通过这个类我们可以看到它继承了 Proxy 同时也实现了 Ticket接口,在getTicket()方法里面调用了
super.h.invoke(this, m3, null);
// Decompiled by DJ v3.7.7.81 Copyright 2004 Atanas Neshkov Date: 2013/2/4 17:29:40
// Home Page : http://members.fortunecity.com/neshkov/dj.html - Check often for new version!
// Decompiler options: packimports(3)
t.getTicket();
原理说明:
通过调用 Proxy.newProxyInstance()方法,用来生成Proxy0类,这个类其实也是实现了Ticket接口的动态生成的类,当我们调用t.getTicket()方法的时候,其实我们调用的是Proxy0类里面的 getTicket()方法,这个方法的里面又开始调用了实现了InvocationHandler接口的ProxyTicket对象的public Object invoke(Object proxy, Method method, Object[] args) throws Throwable 这个方法,这个方法又调用了TicketImpl里面的getTicket()方法;
具体步骤如下:
一、调用Proxy.newProxyInstance方法
1、调用Class cl = getProxyClass(loader, interfaces);方法返回Proxy0类
getProxyClass方法如下步骤:
1,)byte[] proxyClassFile = ProxyGenerator.generateProxyClass( proxyName, interfaces);调用这个方式生成一个实现了Ticket接口的Proxy0类字节码数据,
2,) proxyClass = defineClass0(loader, proxyName,proxyClassFile, 0, proxyClassFile.length);把字节数据生成一个Class
2、生成的Proxy0的源代码如下,通过这个类我们可以看到它继承了 Proxy 同时也实现了 Ticket接口,在getTicket()方法里面调用了
super.h.invoke(this, m3, null);
// Decompiled by DJ v3.7.7.81 Copyright 2004 Atanas Neshkov Date: 2013/2/4 17:29:40
// Home Page : http://members.fortunecity.com/neshkov/dj.html - Check often for new version!
// Decompiler options: packimports(3)
import java.lang.reflect.*;
import proxy_pattern.move_proxy_sun.Ticket;
import proxy_pattern.move_proxy_sun.Ticket;
public final class ProxySubject extends Proxy
implements Ticket
{
implements Ticket
{
public ProxySubject(InvocationHandler invocationhandler)
{
super(invocationhandler);
}
{
super(invocationhandler);
}
public final boolean equals(Object obj)
{
try
{
return ((Boolean)super.h.invoke(this, m1, new Object[] {
obj
})).booleanValue();
}
catch(Error _ex) { }
catch(Throwable throwable)
{
throw new UndeclaredThrowableException(throwable);
}
}
{
try
{
return ((Boolean)super.h.invoke(this, m1, new Object[] {
obj
})).booleanValue();
}
catch(Error _ex) { }
catch(Throwable throwable)
{
throw new UndeclaredThrowableException(throwable);
}
}
public final void getTicket()
{
try
{
super.h.invoke(this, m3, null);
return;
}
catch(Error _ex) { }
catch(Throwable throwable)
{
throw new UndeclaredThrowableException(throwable);
}
}
{
try
{
super.h.invoke(this, m3, null);
return;
}
catch(Error _ex) { }
catch(Throwable throwable)
{
throw new UndeclaredThrowableException(throwable);
}
}
public final int hashCode()
{
try
{
return ((Integer)super.h.invoke(this, m0, null)).intValue();
}
catch(Error _ex) { }
catch(Throwable throwable)
{
throw new UndeclaredThrowableException(throwable);
}
}
{
try
{
return ((Integer)super.h.invoke(this, m0, null)).intValue();
}
catch(Error _ex) { }
catch(Throwable throwable)
{
throw new UndeclaredThrowableException(throwable);
}
}
public final String toString()
{
try
{
return (String)super.h.invoke(this, m2, null);
}
catch(Error _ex) { }
catch(Throwable throwable)
{
throw new UndeclaredThrowableException(throwable);
}
}
{
try
{
return (String)super.h.invoke(this, m2, null);
}
catch(Error _ex) { }
catch(Throwable throwable)
{
throw new UndeclaredThrowableException(throwable);
}
}
private static Method m1;
private static Method m3;
private static Method m0;
private static Method m2;
private static Method m3;
private static Method m0;
private static Method m2;
static
{
try
{
m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] {
Class.forName("java.lang.Object")
});
m3 = Class.forName("proxy_pattern.move_proxy_sun.Ticket").getMethod("getTicket", new Class[0]);
m0 = Class.forName("java.lang.Object").getMethod("hashCode", 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());
}
}
}
{
try
{
m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] {
Class.forName("java.lang.Object")
});
m3 = Class.forName("proxy_pattern.move_proxy_sun.Ticket").getMethod("getTicket", new Class[0]);
m0 = Class.forName("java.lang.Object").getMethod("hashCode", 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());
}
}
}
3、Constructor cons = cl.getConstructor(constructorParams); return (Object) cons.newInstance(new Object[] { h });
动过反射生成一个对象,然后把InvocationHandler类型的ProxyTicket类注入到Proxy0的类里面,当调用Proxy0的 getTicket()方法的时候就会调用super.h.invoke(this, m3, null);这个方法,那么super.h.invoke()这个方法就是调用了InvocationHandler接口的ProxyTicket类,那么ProxyTicket里面的invoke()方法就会通过method.invoke(obj, args);反射的机制来调用这个方法,那么具体的被代理对象就会被执行
要是不明白method.invoke(obj, args)这个方法的意思可以做如下一个例子
Method method=Ticket.class.getMethods()[0];
method.invoke(obj, null);
你会发现这个方法就执行了,Method这个是通过反射来生成的接口方法。
- java 动态代理原理详解
- java动态代理原理
- Java动态代理原理
- java动态代理原理
- Java动态代理详解
- java动态代理详解
- Java动态代理详解
- java动态代理详解
- 详解java动态代理
- java 动态代理详解
- Java动态代理详解
- java动态代理详解
- JAVA动态代理详解
- Java动态代理详解
- Java动态代理详解
- java动态代理详解
- Java动态代理详解
- java动态代理详解
- xcode4利用Interface Builder布局时如何调整不同控件之间的叠放次序
- JAVA基础
- c#使用XSLT将xml文档转换为html文档
- bit相关算法实现
- Linux USB 鼠标驱动程序详解
- java 动态代理原理详解
- 解决iphone链接局域网或wifi热点自动跳转到www.apple.com问题
- 通用软件注册功能之建立有效的软件保护机制
- c#破解验证码示例代码
- 自动处理【任务单工序移动接口表】程序
- Android中常用的位图操作
- 验证是否支持html5的Video标签及MP4视频播放
- Cocos2d-x 游戏中子弹的设计(一)
- 用java实现二叉查找树、堆和优先队列