代理模式深入学习(一)——动态代理的实现及解析

编程入门 行业动态 更新时间:2024-10-08 19:41:22

代理<a href=https://www.elefans.com/category/jswz/34/1771241.html style=模式深入学习(一)——动态代理的实现及解析"/>

代理模式深入学习(一)——动态代理的实现及解析

    关于代理模式,就在不久的前的几天,大概是8月17日左右,我带领的小组还曾经被分配任务去给大家讲解代理模式,总共给了两天时间,但是,依然,我们有很多问题没有解决。比如动态代理的一些问题等等。在经历了DRP项目中通过动态代理封装事务后,对动态代理和事务的理解又深了不少!而事务是很早之前就接触过的概念,对于事务的典型例子:银行取钱,我想大家都不陌生,如何与众多方法结合在一起,减少代码冗余,却从没做过。关于这二者的结合,今天一一做一个详细的解释。

一、代理模式

    分为静态和动态代理。静态代理,我们通常都很熟悉。有一个写好的代理类,实现与要代理的类的一个共同的接口,目的是为了约束也为了安全。具体不再多说。这里主要想说的是关于动态代理。我们知道静态代理若想代理多个类,实现扩展功能,那么它必须具有多个代理类分别取代理不同的实现类。这样做的后果是造成太多的代码冗余。那么我们会思考如果做,才能既满足需求,又没有太多的冗余代码呢?——————动态代理。它通过在运行时创建代理类,来适应变化。主要用到的是Reflec中的Proxy和InvocationHandler类。先通过一段代码来理解一下动态代理模式的实现过程:
public class LogHandler implements InvocationHandler {private Object targetObject; //将要代理的对象保存为成员变量//将被代理的对象传进来,通过这个方法生成代理对象public Object newProxyInstance(Object targetObject) {this.targetObject = targetObject;return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),targetObject.getClass().getInterfaces(), this);}//代理模式内部要毁掉的方法public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {System.out.println("start-->>" + method.getName());//方法执行前的操作for (int i=0; i<args.length; i++) {System.out.println(args[i]);}Object ret = null;try {//调用目标方法,如果目标方法有返回值,返回ret,如果没有抛出异常ret = method.invoke(targetObject, args);System.out.println("success-->>" + method.getName()); //方法执行后操作}catch(Exception e) {e.printStackTrace();System.out.println("error-->>" + method.getName());//出现异常时的操作throw e;}return ret;}}
//客户端调用
public static void main(String[] args) {LogHandler logHandler = new LogHandler();UserManager userManager = (UserManager)logHandler.newProxyInstance(new UserManagerImpl());//userManager.addUser("0001", "张三");String name = userManager.findUser("0001");System.out.println("Client.main() --- " + name);}

代码解析

首先我们要了解一下类的加载机制,在每创建一个Java类时,都会生产一个.class文件,在内存中对应也会生成一个class对象,来表示该类的类型信
息,我们可以用.class来获取这个类的所有信息,也可以通过getClass()方法来读取这个类的所有信息,比如
getClass().getInterfaces()获取类的接口信息等。在Java类加载时,要通过一个类加载器classloader来将生成的Java类加载到JVM
中才能执行。理解了类的加载机制后,我们再看代码中的newProxyInstance方法,在这个方法中,我们将被代理对象传进来后,通过Proxy.newProxyInstance这个方法来动态的创建一个被代理类的一个代理类的实例。

在Proxy.newProxyInstance方法中,共有三个参数:

    1、targetObject.getClass().getClassLoader()目标对象通过getClass方法获取类的所有信息后,调用getClassLoader()方法来获取类加载器。获取类加载器后,可以通过这个类型的加载器,在程序运行时,将生成的代理类加载到JVM即Java虚拟机中,以便运行时需要!2、targetObject.getClass().getInterfaces()获取被代理类的所有接口信息,以便于生成的代理类可以具有代理类接口中的所有方法。3、this:我们使用动态代理是为了更好的扩展,比如在方法之前做什么,之后做什么等操作。这个时候这些公共的操作可以统一交给代理类去做。这个时候需要调用实现了InvocationHandler 类的一个回调方法。由于自身变实现了这个方法,所以将this传递过去。

invoke方法的参数

    1、Object proxy生成的代理对象,在这里不是特别的理解这个对象,但是个人认为是已经在内存中生成的proxy对象。2、Method method:被代理的对象中被代理的方法的一个抽象。3、Object[] args:被代理方法中的参数。这里因为参数个数不定,所以用一个对象数组来表示。

执行过程

    在执行过程中,由于被代理的方法可能有返回值,可能直接就是void来表示,那么为了适应于所有方法,所以定义一个返回值,将返回的值通过ret来接收,当然会抛出异常。ret = method.invoke(targetObject, args);就是调用被代理对象的方法,来执行最原始的方法。在执行完后,进行额外的处理操作。以上就是在学习代理模式中自己的一些理解。代理模式是一个很重要的模式,也是一个很实用的模式,利用它可以实现事务的封装,不用我们每次需要事务操作时,都要进行手动去写,直接调用代理就好了,具体见下篇博客。

更多推荐

代理模式深入学习(一)——动态代理的实现及解析

本文发布于:2024-02-06 02:34:54,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1745908.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:模式   动态

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!