天天看点

动态代理1、什么是动态代理?2、主要技术3、动态代理的用途4、动态代理的两种表现形式5、动态代理各个角色分析6、动态代理的优点

  动态代理就是在运行时生成一个类,这个类会实现你指定的一组接口,而这个类没有.java文件,是在运行时生成的,你也不用去关心它是什么类型的,你只需要知道它实现了哪些接口即可。

  平常实现一个接口需要写一个具体的实现类,而动态代理技术能够在运行期间动态的生成实现指定接口的实现类对象,底层使用的反射原理。在框架中经常使用,例如:struts1、struts2、spring和hibernate等等。学习动态代理可以更好的理解框架内部的原理。

  创建动态代理的方法:

  上面代码中,proxy类的静态方法newproxyinstance()方法生成了一个对象,这个对象实现了数组中指定的接口。proxy类的静态方法newproxyinstance()方法返回的是实现了指定接口的实现类对象。

  newproxyinstance()方法的参数:

    classloader loader:它是类加载器类型,myinterface.class.getclassloader()就可以获取到classloader对象,只要有一个class对象就可以获取到classloader对象;

    class[] interfaces:指定newproxyinstance()方法返回的对象要实现哪些接口,可以指定多个接口,例如上面例子我们只指定了一个接口;

    invocationhandler h:它是最重要的一个参数,是一个接口!叫做调用处理器,无论你调用代理对象的什么方法,都是在调用invocationhandler的invoke()方法!

  invocationhandler的invoke()方法:

  invocationhandler的invoke()方法的参数有三个:

    object proxy:代理对象,也就是proxy.newproxyinstance()方法返回的对象,通常不用;

    method method:表示当前被调用方法的反射对象;

    object[] args:表示当前被调用方法的参数,没有参数的args是一个零长数组。

  invoke()方法的返回值为object类型,它表示当前被调用的方法的返回值,没有返回值的invoke()返回的就必须是null。

  动态代理作为代理模式的一种扩展形式,广泛应用于框架(尤其是基于aop的框架)的设计与开发,动态代理的用途与装饰模式很相似,就是为了对某个对象进行增强。所有使用装饰者模式的案例都可以使用动态代理来替换。

  在java类加载器中也应用了代理模式,例如我们自己写的person类,一定是存放到classpath中,那么一定是由系统类加载器来加载。当系统类加载器来加载类时,它首先把加载的任务交给扩展类加载去,如果扩展类加载器加载成功了,那么系统类加载器就不会再去加载。这就是代理模式了!

  代理模式保证了jdk中的类一定是由引导类加载器加载的!这就不会出现多个版本的类,这也是代理模式的好处。

  给出invocationhandler接口具体实现类:

  接口:

  

  接口实现类(待增强对象所属类):

  invocationhandler实现类:

  测试类:

  这样,根据执行方法的不同就会调用不同的效果了。

  使用内部类形式:

  因为这个没有给出invocationhandler接口实现类,所以需要使用匿名内部类的形式。

  抽象角色:声明真实对象和代理对象的共同接口,这样一来在任何可以使用目标对象的地方都可以使用代理对象。

  代理角色:代理对象内部含有目标对象的引用,从而可以在任何时候操作目标对象;代理对象提供一个与目标对象相同的接口,以便可以在任何时候替代目标对象。代理对象通常在客户端调用传递给目标对象之前或之后,执行某个操作,而不是单纯地将调用传递给目标对象,同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装。

  真实角色:定义了代理对象所代表的目标对象,代理角色所代表的真实对象,是我们最终要引用的对象,定义了代理对象所代表的目标对象。

  减少编程的工作量:假如需要实现多种代理处理逻辑,只要写多个代理处理器就可以了,无需每种方式都写一个代理类。

  系统扩展性和维护性增强,程序修改起来也方便多了(一般只要改代理处理器类就行了)。

  做方法的增强,可以在不修改源码的情况下,增强一些方法,实现无侵入式的代码扩展。

动态代理1、什么是动态代理?2、主要技术3、动态代理的用途4、动态代理的两种表现形式5、动态代理各个角色分析6、动态代理的优点