【Mybatis源码分析 13】mybatis核心思想-动态代理,由此梳理一下反射、动态代理及其和静态代理的区别

目录

静态代理

动态代理

反射

Proxy

InvocationHandler

代理

是通过代理对象访问目标对象,可以在不修改被代理对象的基础上,通过扩展代理类,进行一些功能的附加与增强。

静态代理

运行前就定义好了静态代理类和被代理类之间的关系,并且静态代理类和被代理类应该共同实现同一个接口。

静态代理实现了目标对象的所有方法,一旦目标接口增加方法,代理对象和目标对象都要进行相应的修改,增加维护成本。

 

动态代理

通过代理对象将被代理对象的方法和参数传递给InvocationHandler的invoke方法统一执行。

其中涉及三个重要的内容:反射、Proxy(代理类)、InvocationHandler(代理事件处理器)

反射

在运行状态中,对于任意的一个类,都能够知道这个类的所有属性和方法,对任意一个对象都能够通过反射机制调用一个类的任意方法,这种动态获取类信息及动态调用类对象方法的功能称为java的反射机制

也就是说,在运行时,通过Class.forName("类的全限定名") or "类的全限定名".class or 类的实例.getClass()获取一个类的类型,通过这个类型调用 getDeclaredFields()、getDeclaredMethods() 、getDeclaredConstructors()  等能够知道这个类的所有属性(Fileds)和方法(Methods)和构造器( Constructors)等。通过invoke(类的实例对象或代理对象,参数args)执行方法的机制称为反射

动态代理的实现就是利用了反射机制获取代理类的类型和方法

Proxy

为解决静态代理对象必须实现接口的所有方法的问题,Java给出了java.lang.reflect.Proxy实现动态代理,不需要预先implement接口(因此也不需要显式地实现所有的接口方法),统一通过Proxy代理类的invoke方法执行接口方法。

java.lang.reflect.Proxy提供静态方法newProxyInstance创建一个指定类型和代理事件执行器的接口代理对象

参数说明:

ClassLoader loader: 指定类加载器

Class<?>[] interfaces: 需要代理的接口类型

InvocationHandler h: 代理事件执行器,implement InvocationHandler接口的实现类的实例(实现InvocationHandler的invoke方法,通过代理对象传入的被代理类方法和参数来执行)

    @CallerSensitive
    public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h) {
        Objects.requireNonNull(h);

        final Class<?> caller = System.getSecurityManager() == null
                                    ? null
                                    : Reflection.getCallerClass();

        /*
         * Look up or generate the designated proxy class and its constructor.
         */
        Constructor<?> cons = getProxyConstructor(caller, loader, interfaces);

        return newProxyInstance(caller, cons, h);
    }

InvocationHandler

InvocationHandler 接口只有一个invoke方法,负责处理被代理对象的操作。

package MyConfig;

import org.apache.ibatis.annotations.Select;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class MyInvocationHandler implements InvocationHandler {
    

    /**
     * 动态代理获取接口方法,解析执行
     * @param proxy    接口代理对象
     * @param method  代理对象传入的方法
     * @param args    代理对象传入的参数
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        // 对方法解析和执行
        // 返回结果
        return null;
    }
}

mybatis的接口映射方法的执行就是通过动态代理实现的,通过org.apache.ibatis.binding.MapperProxy实现的InvocationHandler接口的invoke方法,将dao方法委托为org.apache.ibatis.binding.MapperMethod执行(execute)

【Mybatis源码分析 8】mybatis的mapper接口中dao方法并没有具体实现类,是怎么通过mapper动态代理运行的

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值