1、前言
写动态代理的代码涉及了一个非常重要的类 Proxy,通过Proxy的静态方法newProxyInstance才会动态创建代理对象。
2、newProxyInstance方法
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
三个参数分别表示: loader表示类加载器, interfaces表示代码要用来代理的接口 , h表示一个 InvocationHandler 对象,前面两个参数容易理解,
最后一个InvocationHandler是什么?
InvocationHandler是一个接口,官方文档解释说,每个代理的实例都有一个与之关联的 InvocationHandler 实现类,如果代理的方法被调用,那么代理便会通知和转发给内部的 InvocationHandler 实现类,由它决定处理。
public interface InvocationHandler { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable; }
InvocationHandler 内部只有一个 invoke() 方法,正是这个方法决定了怎么样处理代理传递过来的方法调用。其中参数proxy表示代理对象,method表示代理对象调用的方法,args表示调用的方法中的参数。所以Proxy动态产生的代理会调用InvocationHandler实现类,所以InvocationHandler才是实际执行者。
3、代码实例
//抽象主题 interface AbstractSubject { void request(); } //真实主题 class RealSubject implements AbstractSubject { public void request() { System.out.println("访问真实主题方法..."); } } //真实主题 class RealSubject1 implements AbstractSubject { public void request() { System.out.println("访问真实主题方法1..."); } } //动态代理类 class DynamicProxy implements InvocationHandler { private Object object; public DynamicProxy(Object object) { this.object = object; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { before(); Object result = method.invoke(object, args); after(); return result; } private void before() { System.out.println("hello!"); } private void after() { System.out.println("bye!"); } } //测试类 public class TestDynamicProxyPattern { public static void main(String[] args) { AbstractSubject abstractSubject = new RealSubject(); DynamicProxy dynamicProxy = new DynamicProxy(abstractSubject); Proxy.newProxyInstance(abstractSubject.getClass().getClassLoader(), abstractSubject.getClass().getInterfaces() , dynamicProxy); abstractProxy.request(); } }
上述动态代理只需要传入需要被代理类的对象(DynamicProxy dynamicProxy = new DynamicProxy(abstractSubject)),然后调用Proxy类的工厂方法newProxyInstance去动态地创建一个代理类,最后调用代理类的方法便实现了“增强功能”。使用了动态代理之后,无论有多少类多少方法需要增加逻辑,只需要在使用的时候将类对象传入得到代理对象,然后使用代理对象调用需要增强的方法即可。
所以这时候如果增加一个实现抽象主题的真是主题类,比如说叫做RealSubject1,这个时候只要只要把该类的对象传入动态代理类DynamicProxy中,通过接口又可以实现接口AbstractSubject的实现类。
这样来实现:
AbstractSubject abstractSubject1 = new RealSubject1();
DynamicProxy dynamicProxy = new DynamicProxy(abstractSubject1);
4、总结
1、区别于静态代理的生成代理类,动态代理的代理类通过 Proxy.newInstance() 方法生成。静态代理和动态代理的区别是在于要不要开发者自己定义 Proxy 类。
2、不管是静态代理还是动态代理,代理与被代理者都要实现接口,还是要是面向接口编程,目的都是增强现有功能。
3、动态代理通过 Proxy 动态生成 proxy class,但是它也指定了一个 InvocationHandler 的实现类。
4、动态代理也有缺陷,它要求需要代理的对象必须实现了某个接口,而且也不够灵活,动态代理会为接口中的声明的所有方法添加上相同的代理逻辑。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。
Proxy 动态代理是 jfinal AOP 的底层实现机制。jfinal 4.0 版本新增了 com.jfinal.proxy 模块用于消除对 cglib/asm 的依赖来实现动态代理。 proxy 模块需要运行在 JDK 环境之下,如果需要运行在 JRE 之下,可以添加如下配置来支持: public void configConstant(Constants me) { // 4.6 之
本文向大家介绍Java 动态代理原理分析,包括了Java 动态代理原理分析的使用技巧和注意事项,需要的朋友参考一下 Java 动态代理原理分析 概要 AOP的拦截功能是由java中的动态代理来实现的。说白了,就是在目标类的基础上增加切面逻辑,生成增强的目标类(该切面逻辑或者在目标类函数执行之前,或者目标类函数执行之后,或者在目标类函数抛出异常时候执行。Spring中的动态代理是使用Cglib进行实
本文向大家介绍详解Java JDK动态代理,包括了详解Java JDK动态代理的使用技巧和注意事项,需要的朋友参考一下 今天来看看Java的另一种代理方式——JDK动态代理 我们之前所介绍的代理方式叫静态代理,也就是静态的生成代理对象,而动态代理则是在运行时创建代理对象。动态代理有更强大的拦截请求功能,因为可以获得类的运行时信息,可以根据运行时信息来获得更为强大的执(骚)行(操)力(作)。
本文向大家介绍Java JDK动态代理的基本原理详细介绍,包括了Java JDK动态代理的基本原理详细介绍的使用技巧和注意事项,需要的朋友参考一下 JDK动态代理详解 本文主要介绍JDK动态代理的基本原理,让大家更深刻的理解JDK Proxy,知其然知其所以然。明白JDK动态代理真正的原理及其生成的过程,我们以后写JDK Proxy可以不用去查demo,就可以徒手写个完美的Proxy。下面首先来个
本文向大家介绍详解java JDK 动态代理类分析(java.lang.reflect.Proxy),包括了详解java JDK 动态代理类分析(java.lang.reflect.Proxy)的使用技巧和注意事项,需要的朋友参考一下 详解java JDK 动态代理类分析(java.lang.reflect.Proxy)
本文向大家介绍详细分析java 动态代理,包括了详细分析java 动态代理的使用技巧和注意事项,需要的朋友参考一下 1、动态代理的特点: 字节码随用随创建,随用随加载 2、作用: 不修改源码的基础上对源码进行加强 3、分类: (1)基于接口的动态代理: 涉及到的类:Proxy,由JDK官方提供,使用Proxy类中的newProxyInstance方法创建对