• 动态代理


    mybatis中用了不少设计模式,其中mappr接口调用使用了动态代理:

    代理模式

      • 代理

        • 静态代理
        • 事件一般用接口或者抽象类
        • 代理类(实现这个事件 必须东这个事件才能代理) 包含被代理的事件的主角
        • 事件的主角(也实现这个事件) 被代理的对象
        • 静态代理 只对一个熟悉 不具备通用性

        • 动态代理
        • 专门做动态代理的接口 implements InvocationHander
          • 重写invoke方法 什么都可以
          • 把目标和代理对象捏合成一个新的对象(新的代理类 才能去代理),在捏合的过程中,把目标的类加载器 接口还有代理对象都传递给proxy.newProxyInstance方法
          • getInterfaces() 通过反射获得接口数组
        • jdk下面的Proxy对象下的newInstance,要求必须要有事件,委托人必须要实现事件的接口
        • cglib字节码修改器
          • 性能更高

          • 直接通过类加载器 对类的字节文件进行修改

          • 类加载器:将磁盘中的文件通过io流加载到内存中。加载到内存中才能对类进行修改。

          • 代理一般使用CGLIBProxy

          • 不要忘记导入jar包 asm cglib javassist

        一个类代表另一个类,创建现有对象的对象,以便向外界提供功能接口。 向在访问这个类的时候做一些控制的时候可以使用代理模式 增加中间层,实现与被代理类的组合。

        优点----为什么时候代理模式

        • 职责清晰 高扩展性 智能化

        • 当你在访问一个对象的时侯想要对这个类进行一些控制,(装饰者模式是增强功能)

        • 提供了对目标对象另外的访问方式。通过代理对象来访问目标对象,好处:可以在目标对象的基础上增加额外的功能来扩展目标对象的功能。

        • 当你想要对要使用的对象进行修改的时候,不要直接在源码上进行修改,而是使用代理工厂的模式 使用代理类来实现你想的功能

        应用

        1. 远程代理: 为一个对象在不用的地址空间提供局部代表,这样可以隐藏一个对象存在于不同地址空间的事实。
        2. 虚拟代理:根据需要创建开销很大的对象。通过它来存放实例化需要很长时间的真实对象。
        3. 安全代理:用来控制真实对象访问时的权限
        4. 智能指引:指调用真实对象时,代理处理另外一些事。
          应用实例
        • 火车票不仅可以在火车站买也可以在车代售点买。
        • 一个人A变换成另一个人B的模样,将B的外貌抽象出来,A B都实现了这个接口,用户C访问A的时候 看不出A不是B 所以可说A是B的代理类。 以说A是B的代理类。

        代理模式的分类

        • 代理的实现 聚合和继承

        动态代理模式(不知道代理类的名称 直接产生代理对象)

        解决类太多的问题

        • 继承:不宜与扩展

        • 聚合(使用接口的方式):一个类A中有另外一个类B的对象(接口),两个类实现相同的接口,但是在一个类A中调用的是另一个类B的方法。 A就是B的一个代理,因为在A中调用的方法是B的方法

          • 通过接口来实现代理
          • 比较灵活,可以随意地调换代理事务的顺序。
        • 实现动态的编译

          • JavaCompiler(java的编译器 javac)

        静态代理(需要知道代理类的类名)

        一个代理类 和 触发人 实现接口 一个代理类只有一个功能

        • 实现动态代理模式的方式有两种:

          • 依赖jdk的Proxy对象下的newProxyInstance()

            • 注意事项:必须要救要有事件,委托人必须要实现事件接口
            • 代理人实现InvocationHander接口 重写invoke方法 在invoke方法中做一些代理的额处理,通过method.invoke(this.obj,args) 来调用委托人的方法
            • 调用的时候将代理人和委托人通过(代理类)Procy.newProxyInstance(委托类.getClassLoader(),委托类.getInterfaces(),代理类);
          • cglib字节码修改器实现代理

            • 于jdk中的实现动态代理方式不同的就是,委托人不需要实现特定的接口
            • 需要导入 ams.jar 和 cglib.jar 和 javassist.jar
            • 核心类 Enhancer
            • 委托类不需要实现接口, 代理类要实现MethodInterceptor接口 使用回调的方法,效率比proxy要快
            • 在代理类中写createProxy方法
          public Object createProxy(Object target){
          this.obj = target;
          Enhancer enhancer = new Enhancer();
          //设置被代理对象目标
          enhancer.setSuperclass(this.obj.getClass());
          //回调  调用下面的intercept(..)方法
          enhancer.setCallback(this);
          enhancer.setClassLoader(target.getClass().getClassLoader());
          return enhancer.create();
        • 调用:
        Target t = new Target(); MyProxy my = new MyProxy(); Target t2 = (Target) my.createProxy(t); t2.getMsg("sdsf");
        
  • 相关阅读:
    bzoj1966:[AHOI2005]病毒检测
    bzoj2938:[Poi2000]病毒
    bzoj3172:[Tjoi2013]单词
    luoguP3808[模板]AC自动机(简单版)
    luoguP3796[模板]AC自动机(加强版)
    Java 基本类型、封装类型、常量池、基本运算
    Java 内存分配(转)
    Java 数组ArrayList语法
    Java的修饰、继承、接口、抽象类
    2019数模国赛有感
  • 原文地址:https://www.cnblogs.com/lizhen-home/p/7922237.html
Copyright © 2020-2023  润新知