日期:2014-05-20  浏览次数:20659 次

动态代理问题
用Proxy的newProxyInstance创建一个代理对象时,第三个参数会指定一个实现了Invocationandld的类,然后调用目标对象的方法就会被拦截到invoke方法,为什么会自动调用呢?此外像FilenameFilter的accept方法也回自动调用,源码怎么实现的?

------解决方案--------------------
直接加个断点跟踪 看源码就可以了。首先需要关联上源码。按着ctrl 点就可以了。

参考 

http://blog.csdn.net/zjx2388/archive/2009/05/19/4201379.aspx
------解决方案--------------------
这两种方式有本质的不同,第一种方式是通过反射调用的,第二种只是简单的回调。

------解决方案--------------------
查看下源代码就知道了

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

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;
    }
    
}