JAVA动态代理初解

JAVA动态代理初解

    代理模式:简单来讲就是一件事情由另外的对象去代为操作。最简单的实例,写了个接口,一个类去实现这个接口中的方法,但是突然有一天要对方法增加比如日志记录,访问权限等功能时,那么我们可以写另外一个类去实现接口中的方法,然后增加比如日志记录,访问权限的代码,引用原类中的方法完成封装。但是这样会存在一个问题,就是系统中的类的数量会扩大,导致系统运行的内存占用越来越大(新的类与原来的类都会占用内存),所以JAVA提供了针对接口的动态代理模式。为什么叫动态了,因为其用了JAVA反射机制,通过反射接口的class对象来封装产生新的class对象,并通过系统提供的InvocationHandler接口来增加对原方法的功能的扩充。

    比如:Proxy代理对象类中的newProxyInstance,其用来创建代理对象。

    public static Object newProxyInstance(ClassLoader loader,

                                          Class<?>[] interfaces,

                                          InvocationHandler h)

    throws IllegalArgumentException

    源代码中:

 final InvocationHandler ih = h;

 final Class<?>[] intfs = interfaces.clone();//可以看到首先对接口进行复制

 Class<?> cl = getProxyClass0(loader, intfs);//接着将接口class与类加载器一起封装产生新的class对象

 final Constructor<?> cons = cl.getConstructor(constructorParams);//根据参数得到构造方法

 而构造方法中的参数constructorParams,为一个InvocationHandler.class 

 private static final Class<?>[] constructorParams = { InvocationHandler.class };

    最后返回return newInstance(cons, ih);

换句话说,代理对象就是通过封装原接口,并扩充一个新接口,功能的新增实现在新接口的invoke()

 public Object invoke(Object proxy, Method method, Object[] args)

        throws Throwable;

即可以在这个方法中添加新的功能代码,然后通过原类的Method来调用原方法。

Object obj=method.invoke(test, args);test:被代理的类,args:方法参数


这样当Proxy调用newProxyInstance生成代理对象,调用被代理类中的方法时,会进入到InvocationHandler接口实现类中的invoke()方法去增加新功能,调用被代理类的原方法。




你可能感兴趣的:(java,动态代理,代理初解)