关于java中的动态代理.

1. 什么是动态代理?

代理模式为一种设计模式,其目的就是为其他对象提供一个代理以控制对某个真实对象的访问。代理类负责为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后续处理

动态代理的意思就是在程序运行时生成委托类的代理类来实现增强的功能。

2. 动态代理有哪些实现方式?

2.1 jdk本身自带的动态代理类。

由JVM在程序运行时生成代理类,使用java反射机制。
  • demo
public class MyInvocationHandler implements InvocationHandler {

    private Object target;
    
    // 通过此方法可以生成委托类的代理类,原理通过传入的委托类的对象的类加载器生成一个代理类对象 
    public Object bind(Object target, Class[] interfaces) {
        this.target = target;
        //取得代理对象,通过被代理对象的类加载器,生成代理对象
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),
                interfaces, this);
    }

    // 通过此方法增强委托类中的方法
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("增强内容前!");
        Object invoke = method.invoke(target, args);
        System.out.println("增强内容后!");
        return invoke;
    }
}


--------------------------------------------------------------------------------------------------------------------------------------------
    public static void main(String[] args) {
        MyInvocationHandler myInvocationHandler = new MyInvocationHandler();
        TestInterface test = new com.thunisoft.casespace.common.dtdl.Test();
        TestInterface bind =(TestInterface) myInvocationHandler.bind(test, new Class[]{TestInterface.class});
        bind.test();
        bind.test2();
    }

  • newProxyInstance源码分析:
    ···
    public static Object newProxyInstance(ClassLoader loader,
    Class<?>[] interfaces,
    InvocationHandler h)
    throws IllegalArgumentException
    {
    // 调用处理程序(实现InvocationHandler接口的实现类)不为空
    Objects.requireNonNull(h);
    // 拷贝对象,设置成为常量
    final Class<?>[] intfs = interfaces.clone();
    // 调用java安全管理器
    final SecurityManager sm = System.getSecurityManager();
    if (sm != null) {
    checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
    }

      /*
       * Look up or generate the designated proxy class
       * 查找或者生成指定的代理类,该步骤会 查询 proxyClassCache 代理类缓存中是否存在该指定类型的代理类,如果不存在则生成
       */
      Class<?> cl = getProxyClass0(loader, intfs);
    
      /*
       * Invoke its constructor with the designated invocation handler.
       * 使用指定的调用处理程序调用其构造函数。
       */
      try {
          if (sm != null) {
              checkNewProxyPermission(Reflection.getCallerClass(), cl);
          }
          // 调用有参的构造函数生成类构造器
          final Constructor<?> cons = cl.getConstructor(constructorParams);
          final InvocationHandler ih = h;
          if (!Modifier.isPublic(cl.getModifiers())) {
              AccessController.doPrivileged(new PrivilegedAction<Void>() {
                  public Void run() {
                      cons.setAccessible(true);
                      return null;
                  }
              });
          }
          // 创建对象
          return cons.newInstance(new Object[]{h});
      } catch (IllegalAccessException|InstantiationException e) {
          throw new InternalError(e.toString(), e);
      } catch (InvocationTargetException e) {
          Throwable t = e.getCause();
          if (t instanceof RuntimeException) {
              throw (RuntimeException) t;
          } else {
              throw new InternalError(t.toString(), t);
          }
      } catch (NoSuchMethodException e) {
          throw new InternalError(e.toString(), e);
      }
    

    }
    ···

2.2 ASM、cglib(基于 ASM)、Javassist 等方式

该方式后续在补充。
AccessibleObject.setAccessible方法,可以在运行时更改类属性的作用域,可以通过他绕开类的api访问控制.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容

  • 动态代理的介绍 动态代理是一种在运行时动态地创建代理对象,动态地处理代理方法调用的机制。 实际上它是一种代理机制。...
    4553675200ad阅读 550评论 0 0
  • 一、概述   代理模式我们接触的就比较多了,所谓的代理模式就是,给某一个对象提供一个代理对象,并由代理对象控制对原...
    骑着乌龟去看海阅读 883评论 0 9
  • 谈谈 Java 反射机制,动态代理是基于什么原理?小编整理了一些java进阶学习资料和面试题,需要资料的请加JAV...
    君不见_c4ee阅读 259评论 0 0
  • 简介&目录 上一章 新王 我将姥姥的尸骨火化,将骨灰洒在大仓山。 我朦胧地开始明白,姥姥心中的矛盾。她既孕育了狼人...
    等风的叶阅读 328评论 1 5
  • 霍妮总结绝望说:“绝望感是未解决的冲突的终结,其根源是曾经全心全意,心无旁婺的绝望,童年非常困难的,创伤性的冲突中...
    雪辉心语阅读 99评论 0 0