彩票走势图

Spring架构详解(11):动态代理的实现原理

转帖|行业资讯|编辑:郝浩|2016-02-25 11:55:03.000|阅读 1184 次

概述:要了解Spring的AOP就必须先了解的动态代理的原理,因为AOP就是基于动态代理实现的。动态代理还要从JDK本身说起。

# 慧都年终大促·界面/图表报表/文档/IDE等千款热门软控件火热促销中 >>

相关链接:

前面介绍了Spring容器的构建过程,那Spring能为我们做什么,Spring的Ioc容器又能做什么呢?我们使用Spring必须要首先构建Ioc容器,没有它Spring无法工作,ApplicatonContext.xml就是Ioc 容器的默认配置文件,Spring的所有特性功能都是基于这个Ioc容器工作的,比如后面要介绍的AOP。

Ioc它实际上就是为你构建了一个魔方,Spring为你搭好了骨骼架构,这个魔方到底能变出什么好的东西出来,这必须要有你的参与。那我们怎么参与?这就是前面说的要了解Spring中那有些扩展点 ,我们通过实现那些扩展点来改变Spring的通用行为。至于如何实现扩展点来得到我们想要的个性结果,Spring中有很多例子,其中AOP的实现就是Spring本身实现了其扩展点来达到了它想要的特性功能 ,可以拿来参考。

要了解Spring的AOP就必须先了解的动态代理的原理,因为AOP就是基于动态代理实现的。动态代理还要从JDK本身说起。

在Jdk的java.lang.reflect包下有个Proxy类,它正是构造代理类的入口。这个类的结构入下:

Bean实例创建流程图
Proxy类结构

从上图发现最后面四个是公有方法。而最后一个方法newProxyInstance就是创建代理对象的方法。这个方法的源码如下:

public static Object newProxyInstance(ClassLoader loader,    
 
    Class>  [] interfaces,  
 
    InvocationHandler h)    
 
    throws IllegalArgumentException {    
 
     
 
        if (h == null) {    
 
        throw new NullPointerException();    
 
    }  
 
    Class cl = getProxyClass  (loader, interfaces);  
 
    try {    
 
        Constructor cons = cl.getConstructor(constructorParams);    
 
        return (Object) cons.newInstance(new Object[]   { h });  
 
    } catch (NoSuchMethodException e) {    
 
        throw new InternalError(e.toString());    
 
    } catch (IllegalAccessException e) {    
 
        throw new InternalError(e.toString());    
 
    } catch (InstantiationException e) {    
 
        throw new InternalError(e.toString());    
 
    } catch (InvocationTargetException e) {    
 
        throw new InternalError(e.toString());    
 
    }  
 
}    

这个方法需要三个参数:ClassLoader,用于加载代理类的Loader类,通常这个Loader和被代理的类是同一个Loader类。Interfaces,是要被代理的那些那些接口。InvocationHandler,就是用于执行 除了被代理接口中方法之外的用户自定义的操作,他也是用户需要代理的最终目的。用户调用目标方法都被代理到InvocationHandler类中定义的唯一方法invoke中。这在后面再详解。

下面还是看看Proxy如何产生代理类的过程,他构造出来的代理类到底是什么样子?下面揭晓啦。

Bean实例创建流程图
创建代理对象时序图

其实从上图中可以发现正在构造代理类的是在ProxyGenerator的generateProxyClass的方法中。ProxyGenerator类在sun.misc包下,感兴趣的话可以看看他的源码。

假如有这样一个接口,如下:

public interface SimpleProxy {  
  
    public void simpleMethod1();    
        
    public void simpleMethod2();  
 
}  

代理来生成的类结构如下:

public class $Proxy2 extends java.lang.reflect.Proxy implements SimpleProxy{    
 
    java.lang.reflect.Method m0;    
 
    java.lang.reflect.Method m1;  
 
    java.lang.reflect.Method m2;  
 
    java.lang.reflect.Method m3;  
 
    java.lang.reflect.Method m4;  
 
     
 
    int hashCode();  
 
    boolean equals(java.lang.Object);  
 
    java.lang.String toString();  
 
    void simpleMethod1();  
 
    void simpleMethod2();  
 
}    

这个类中的方法里面将会是调用InvocationHandler的invoke方法,而每个方法也将对应一个属性变量,这个属性变量m也将传给invoke方法中的Method参数。整个代理就是这样实现的。


标签:

本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@pclwef.cn


为你推荐

  • 推荐视频
  • 推荐活动
  • 推荐产品
  • 推荐文章
  • 慧都慧问
扫码咨询


添加微信 立即咨询

电话咨询

客服热线
023-68661681

TOP