现在的位置: 首页 > 综合 > 正文

Java动态代理

2013年07月10日 ⁄ 综合 ⁄ 共 2062字 ⁄ 字号 评论关闭

1.什么是动态代理? 
2.为什么使用动态代理? 
3.使用它有哪些好处? 
4.哪些地方需要动态代理?
 

--------------------分隔线-----------------------------

和动态代理有关的有两个类 
1.interface InvocationHandler 
Object invoke(Object proxy, Method method, Object[] args) 
只这一个方法,后面再说 

2.class Proxy 
真正表示动态代理的类,提供两个静态方法: 

Class<?> getProxyClass(ClassLoader loader, Class<?>[] interface) 
用来产生代理类,参数要提供interface数组,它会生成这些interface的“虚拟实现”, 
用来冒充真实的对象。 

Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) 
产生代理对象,多了InvocationHandler参数(只是InvocationHandler接口的实现类), 
它与代理对象关联,当请求分发到代理对象后,会自动执行h.invoke(...)方法, 
invoke方法就是我们用来做N多事情的地方 -_-。 

--------------------分隔线-----------------------------

看完上面的代码,大致明白动态代理的含义: 
A接口有c方法,类B实现A接口,原本应该是执行B类中的c方法,可现在不这样做; 
我声明产生B类的代理类B',由它来冒充B类的“兄弟”并“实现”A接口, 
对外界来说B'应该也有c方法,可当真正调用它的时候, 
它会去执行与它关联InvocationHandler的invoke()方法, 
在这个方法里面你可以做很多事情。这样,这个请求就被“代理”到其它地方去了。 

下面是根据我的理解画的一个说明图

--------------------分隔线----------------------------- 

引用网上的一个例子来说明问题(有部分改动,转载自:http://callan.iteye.com/blog/161806) 
真实的接口:

public interface Hello {

    void sayHello(String to);
  
    void print(String p); 
 
}

  它的真实实现类:

public class HelloImpl implements Hello {
    
    public void sayHello(String to) {
        System.out.println("Say hello to " + to);
    }
    
    public void print(String s) {
        System.out.println("print : " + s);
    }
    
}

  在这里生成与代理类相关联的InvocationHandler对象

public class LogHandler implements InvocationHandler {
    
    private Object dele;
    
    public LogHandler(Object obj) {
        this.dele = obj;
    }
    
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        doBefore();
        //在这里完全可以把下面这句注释掉,而做一些其它的事情
        Object result = method.invoke(dele, args);
        after();
        return result;
    }
    
    private void doBefore() {
        System.out.println("before....");
    }
    
    private void after() {
        System.out.println("after....");
    }
}

  最后是测试类:

public class ProxyTest {

    public static void main(String[] args) {
        HelloImpl impl = new HelloImpl();
        LogHandler handler = new LogHandler(impl);
        //这里把handler与impl新生成的代理类相关联
        Hello hello = (Hello) Proxy.newProxyInstance(impl.getClass().getClassLoader(), impl.getClass().getInterfaces(), handler);
        
        //这里无论访问哪个方法,都是会把请求转发到handler.invoke
        hello.print("All the test");
        hello.sayHello("Denny");
    }

}

  这里是输出结果:

before....
print : All the test
after....
before....
Say hello to Denny
after....

 

抱歉!评论已关闭.