浏览 3174 次
精华帖 (0) :: 良好帖 (1) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2011-03-26
InvocationHandler handler = new MyInvocationHandler(...); Class proxyClass = Proxy.getProxyClass( Foo.class.getClassLoader(), new Class[] { Foo.class }); Foo f = (Foo) proxyClass. getConstructor(new Class[] { InvocationHandler.class }). newInstance(new Object[] { handler }); proxyClass 是一份动态生成的字节码,在创建时需指定一个加载器 Foo.class.getClassLoader()(在此可理解为:给他指定一个妈妈),给它一个接口对象数组,即该代理类实现了哪些接口。 调用 Class proxyClass = Proxy.getProxyClass( Foo.class.getClassLoader(), new Class[] { Foo.class }); 即生成了一个动态字节码。通过反射查看它的构造函数,发现它的构造函数需要传递一个InvocationHandler 对象。 其实在生成的动态字节码实现接口的方法中,都是调用了InvocationHandler 对象的invoke方法。 在这里我们可以大概想象生成的动态字节码的内部结构: public classs Xxx$Proxy{ private InvocationHandler invocationHandler ; public Xxx$Proxy(InvocationHandler invocationHandler ){ this.invocationHandler =invocationHandler ; } Method1(Object[] args){ invocationHandler.invoke(this,...); } Method2(Object[] args){ invocationHandler.invoke(this,...); } } 引用 我们在看InvocationHandler 接口,其内部就一个方法
Object invoke(Object proxy, Method method, Object[] args) throws Throwable 需要一个代理对象,方法对象,方法参数。 通常我们在InvocationHandler实现类中,放入真实的角色和Advice(增强功能类)。 在通过反射执行method对象的Invoke方法时,传入真实对象。 上面代理实现是通过分部执行,Proxy类的newProxyInstance(Foo.class.getClassLoader(), new Class[] { Foo.class }, handler); 方法可以一次生成该代理对象,由以上的解释,我们不难想象需要三个参数。即给它个妈妈(加载器),实现了那些接口(接口数组),InvocationHandler对象。 下面是一个动态代理工厂: public class ProxyFactoryBean { private Advice advice; private Object target; public Advice getAdvice() { return advice; } public void setAdvice(Advice advice) { this.advice = advice; } public Object getTarget() { return target; } public void setTarget(Object target) { this.target = target; } public Object getProxy() { Object proxy = Proxy.newProxyInstance( target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler(){ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { advice.beforeMethod(method); Object retVal = method.invoke(target, args); advice.afterMethod(method); return retVal; } } ); return proxy; } 我们可以动态的指定一个代理目标target,和增强功能对象advice。使用getProxy即会生成一个动态代理对象。 该种代理方式,代理的对象必须是实现了某个接口。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2011-03-29
写的很好 看明白了点InvocationHandler的作用,但是对Invoke函数还是有点迷茫 ,下面是《java编程思想》里面的代码:
public class DynamicProxyHandler implements InvocationHandler { private Object proxied; public DynamicProxyHandler(Object proxied) { this.proxied = proxied; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("**** proxy: " + proxy.getClass() + ",method: " + method + ",args: " + args); if (args != null) for (Object arg : args) System.out.println(" " + arg); return method.invoke(proxied, args); } } 对于这里的DynamicProxyHandler中传入的proxied参数,我发现只是把它赋值到这个函数中,并没有在第一个invoke函数中调用 ,就在return中返回了。。还有就是在第一个invoke函数中第一个参数proxy不明白是什么作用 |
|
返回顶楼 | |
发表时间:2011-03-30
Method.invoke 就调用的是要代理的对象proxied的方法
|
|
返回顶楼 | |