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");
      

       

posted on 2017-11-29 19:05  嘚吧嘚吧嘚  阅读(163)  评论(0编辑  收藏  举报