一、原理
静态代理需要在运行之前就写好代理类,这样就造成了代码的大量重复,所以我们通过动态代理在运行时期动态生成业务类的代理类,那么动态代理类是如何实现的呢?
动态代理类的字节码在程序运行时由Java反射机制动态生成,无需程序员手工编写它的源代码。动态代理类不仅简化了编程工作,而且提高了软件系统的可扩展性,因为Java 反射机制可以生成任意类型的动态代理类。
JDK动态代理中包含一个类和一个接口: InvocationHandler接口,和我们定义的一个实现类“Proxy“,这是一个万能的代理类,我们就是通过这个代理类实现动态代理的。
InvocationHandler接口:
1 | public interface InvocationHandler { |
Proxy类:
Proxy类是专门完成代理的操作类,可以通过此类为一个或多个接口动态地生成实现类,此类提供了如下的操作方法:
1 | public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException |
二、实现动态代理
(一)实现类的方式
步骤:
1、创建接口
2、创建被代理类,实现该接口
3、创建代理类
还是使用静态代理中使用的购买二手车的例子
创建接口:
1 | /** |
创建实现接口的被代理类:
1 | /** |
动态代理的关键是如下几行代码:
该处的代理类CarProxy不去实现具体的某个业务接口,而是实现了JDK提供的InvocationHander类。在Proxy中我们不需要知道具体的业务类,即委托类。在运行之前,将委托类和代理类进行解耦,在运行期才进行绑定,是通过这句话实现的:private object target。然后在调用的时候通过getInstance() 传递需要被代理的对象。
创建代理类:
1 | /** |
编写测试类:
1 | /** |
测试结果如下:
(二)匿名内部类的方式
有时候只需要使用一次代理,那么就可以通过匿名内部类的方式来实现了。
步骤:
1、创建接口(通常该接口已经存在)
2、创建被代理类(这一步实际上是为了创建被代理对象,并且通常被代理对象已经存在)
3、以匿名内部类的形式创建代理类
还是针对买二手车的案例进行举例
创建接口:上面已有
创建被代理类:上面已有
以匿名内部类的形式创建代理类:
1 | /** |
测试结果如下:
三、总结
使用动态代理时,其执行的步骤大致如下:
代理对象每调用一个方法时,会执行一次InvocationHandler中的invoke方法,在invoke方法中会通过Method对象来获取代理对象所执行的方法是什么,然后传递参数args给被代理对象的方法,从而执行被代理对象的方法。
关于更多动态代理的使用:Fileter实现敏感词汇过滤
参考自:
谈谈java代理模式的认识二——动态代理(JDK)
Java新手,若有错误,欢迎指正!