Mybatis运行分为两大部分,第一部分是读取配置文件缓存到Configuration对象,用以创建SqlSessionFactory,第二部分是SqlSession的执行过程。
6.1涉及的技术难点简介
所谓的代理模式就是在原有的服务上多加一个占位,通过这个占位去控制服务的访问。
一般而言,动态代理分为两种,一种是JDK反射机制提供的代理,另一种是CGLIB代理。在JDK提供的代理,我们必须要提供接口,而CGLIB则不需要提供接口
6.1.1反射技术
反射调用的最大好处是配置性大大提高,就如同spring ioc容器一样,可以给很多配置设置参数,使得java应用程序能够顺利运行起来,大大提高了Java的灵活性和可配置性,降低模块之间的耦合。
6.1.2 JDK动态代理
1.编写服务类和接口 2.编写代理类,提供绑定和代理方法
代理类的要求是实现InvocationHandler接口的代理方法,当一个对象被绑定后,执行其方法的时候就会进入到代理方法里。 bind(target) invoke(Object proxy,Methodmethod, args)
Proxy.newProxyInstance(target.getClass().getClassLoadeer(),target.getClass().getInterfaces(),this)
一旦绑定后,在进入代理对象方法调用的时候就会到代理类的代理方法上,代理方法有三个参数:第一个是proxy是代理对象,第二个是当前调用的那个方法,第三个是方法的参数。
6.1.3 CGLIB动态代理
实现MethodInterceptor接口
创建代理对象: 通过Enhancer对象的create方法。
回调方法 intercept(Object obj, Method method,Object[] args, MethodProxy proxy)
在mybatis中通常在延迟加载的时候才会用到CGLIB的动态代理。
6.2构建SqlSessionFactory过程
通过SqlSessionFactoryBuilder去构建SqlSessionFactory分为两步:
1. 通过XMLConfigBuilger解析配置的XML文件,读出配置参数,并将读取的数据存入Configuration类中。Mybatis几乎所有的配置都是存在这里的。
2. 使用Configuration对象去创建SqlSessionFactory
6.2.1构建Configuration
它会做如下初始化:properties全局参数、settings设置、typeAliases别名、typeHandler类型处理器、ObjectFactory对象、plugin插件、environment环境、DatabaseIdProvider数据库标识、mapper映射器。
6.2.2映射器的内部组成
MappedStatement:它保存映射器的一个节点(select|insert|delete|update)。包括许多我们配置的SQL、SQL的id、缓存信息、resultMap、parameterType、resultType、languageDriver等重要配置内容。
SqlSource,它是提供BoundSql对象的地方,它是MappedStatement的一个属性。
BoundSql:它是建立SQL和参数的地方。它有3个常用的属性:SQL、parameterObject、parameterMappings。
ParameterObject为参数本身:传递简单对象、POJO、Map或者@Param注解的参数。
如果传递多个参数、没有@param注解,那么MyBatis就会把parameterObject变为一个Map
parameterMappings,是一个List,每一个元素都是ParameterMapping的对象,这个对象会描述我们的参数,包括属性、名称、表达式、javaType、jdbcType、typeHandler等重要信息
6.3 SqlSession运行过程