动态代理问题

jp260715007 2009-10-27 08:53:04
用Proxy的newProxyInstance创建一个代理对象时,第三个参数会指定一个实现了Invocationandld的类,然后调用目标对象的方法就会被拦截到invoke方法,为什么会自动调用呢?此外像FilenameFilter的accept方法也回自动调用,源码怎么实现的?
...全文
84 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
James__Zhan 2009-10-27
  • 打赏
  • 举报
回复
下例演示了回调方法的方式。类似于FilenameFilter的accept方法。

public class RelectTests {

public static void main(String[] args) {

SomeOne s = new SomeOne();
s.daZhaoHu(new Hello(){
@Override
public void sayHello(String name) {
System.out.println("Hello, My Name is " + name);
}
}, "Kitty");

}

}


interface Hello{
void sayHello(String name);
}

class SomeOne{

public void daZhaoHu(Hello h, String name){
h.sayHello(name);
}

}
James__Zhan 2009-10-27
  • 打赏
  • 举报
回复
通过使用动态代理,可以不改变原来方法的运行方式,可以动态在原方法执行前后加入所需的业务逻辑。
比如我们可以为某个接口的所有对象的某个方法加入日志行为,或对象检查以及其他的逻辑。
如下例,我们就为Hello接口的所有子类的sayHello方法加入了一些额外的逻辑,就是在方法的执行前后打印出start和end的信息。

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class RelectTests {

public static void main(String[] args) {
Hello hello1 = (Hello) Proxy.newProxyInstance(Hello.class.getClassLoader(), new Class[] { Hello.class },
new MyInvocationHandler(new MyHello()));

hello1.sayHello("Kitty!");

Hello hello2 = (Hello) Proxy.newProxyInstance(Hello.class.getClassLoader(), new Class[] { Hello.class },
new MyInvocationHandler(new YourHello()));

hello2.sayHello("Kitty!");

}

}


interface Hello{
void sayHello(String name);
}

class MyHello implements Hello{

@Override
public void sayHello(String name) {
System.out.println("Hello!, My name is " + name);
}
}

class YourHello implements Hello{

@Override
public void sayHello(String name) {
System.out.println("Hello!, Your name is " + name);
}

}

class MyInvocationHandler implements InvocationHandler{

private Object delegate;

MyInvocationHandler(Object subject){
this.delegate = subject;
}


@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = null;
System.out.println("Method start");
result = method.invoke(this.delegate, args);
System.out.println("Method end");
return result;
}

}
swandragon 2009-10-27
  • 打赏
  • 举报
回复
查看下源代码就知道了
James__Zhan 2009-10-27
  • 打赏
  • 举报
回复
这两种方式有本质的不同,第一种方式是通过反射调用的,第二种只是简单的回调。
JavaAlpha 2009-10-27
  • 打赏
  • 举报
回复
直接加个断点跟踪 看源码就可以了。首先需要关联上源码。按着ctrl 点就可以了。

参考

http://blog.csdn.net/zjx2388/archive/2009/05/19/4201379.aspx

62,621

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧