动态代理分析

首先要有一个接口,再有一个接口实现类。

其次我们看看Proxy这个类,他有一个方法newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)。返回一个代理实例。既然参数里面有一个InvocationHandler接口的实现类,那么我们就继续看看这个接口。

一般都往InvocationHandler的实现类中添加一个真实实现类的属性。然后构造方法赋值。这个类里面有一个invoke方法,看下他的代码。

 1  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {  
 2           
 3         // 在目标对象的方法执行之前简单的打印一下  
 4         System.out.println("------------------before------------------");  
 5           
 6         // 执行目标对象的方法  
 7         Object result = method.invoke(target, args);  
 8           
 9         // 在目标对象的方法执行之后简单的打印一下  
10         System.out.println("-------------------after------------------");  
11           
12         return result;  
13     }  

他的method.invode(target,args)中target就是真实实现类。

最后主方法里:直接用Proxy.getProxyInstance(classLoader,interfaces,h)返回了一个代理类。

这是表面上的,实际上上述方法返回值如下:

public final class $Proxy11 extends Proxy  
    implements UserService  
{ 
     public $Proxy11(InvocationHandler invocationhandler)  
    {  
        super(invocationhandler);  
    }  
    public final void add()  
    {  
        try  
        {  
            // 实际上就是调用MyInvocationHandler的public Object invoke(Object proxy, Method method, Object[] args)方法,第二个问题就解决了  
            super.h.invoke(this, m3, null);  
            return;  
        }  
        catch(Error _ex) { }  
        catch(Throwable throwable)  
        {  
            throw new UndeclaredThrowableException(throwable);  
        }  
    }
    private static Method m3; 
    static   
    {  
        try  
        {  
           //UserService是个接口
            m3 = Class.forName("dynamic.proxy.UserService").getMethod("add", new Class[0]);  
           
        }  
        catch(NoSuchMethodException nosuchmethodexception)  
        {  
            throw new NoSuchMethodError(nosuchmethodexception.getMessage());  
        }  
        catch(ClassNotFoundException classnotfoundexception)  
        {  
            throw new NoClassDefFoundError(classnotfoundexception.getMessage());  
        }  
    }  
}

总结:也就是说,获取的代理对象.add()。如果有参数的话在这方法里获取到,这个方法里的方法名也有了,再去调用h.invoke(object,method,args[])方法。此时方法里面

Object result = method.invoke(target, args); 这样一调用就行了。
具体的代码可以看这里:http://rejoy.iteye.com/blog/1627405

posted on 2016-11-29 15:55  一个很帅的男人  阅读(158)  评论(0编辑  收藏  举报

导航