Spring源码(1)mybatis核心原理

发布时间:2022-06-26 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了Spring源码(1)mybatis核心原理脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

mybatis整合sPRing大致原理

代理

静态代理 1 代理类 继承 目标类

2.代理类 和 目标类 实现同一接口 ,代理类里面包含一个目标对象。

显而易见的缺点:产生很多代理类,而且 每一个代理类 只能代理指定的目标类。

动态代理 jdk cglib

jdk的:

Proxy.newProxyInstance 方法,第一个参数是类加载器,第二个参数是被代理类所实现的全部接口,

第三个是实现了invocationHandler接口的实现类 的 对象。

=========用的就是直接产生字节码文件,然后JVM就 class.forname .newInstance()创建代理对象。

 

Mybatis的核心之一

我们每次写, 都是写一个DAO的接口。mybatis 是怎么玩的呢?

其实 mybatis 会把对象创建出来,然后把对象给 ioc容器。

mybatis会把接口, 通过 mapPErFactoryBean 生成对象,然后放到IOC中。

怎么生成? 就是通过jdk动态代理。

在使用Mybatis的时候,通过 SQLsession.getMapper(类.class) 的方式,返回一个对象。

这个底层其实就是 proxy.newProxyInstance得到的,也就是代理得到的。

所以:mybatis的和兴功能之一:通过jdk动态代理技,完成对mapper接口的实例化。

Spring源码(1)mybatis核心原理

mybatis 通过MapperFactoryBean创建一个对象然后交给Spring容器!!!

Spring源码(1)mybatis核心原理

class.forname =====得到Class

newInstance=====得到对象。

 

==============================================

build.gradle中添加依赖:

//mybatis核心依赖
implementation group: 'org.mybatis', name: 'mybatis', version: '3.5.9'

implementation group: 'org.mybatis', name: 'mybatis-spring', version: '2.0.6'

implementation group: 'MySQL', name: 'mysql-connector-java', version: '8.0.27'

//spring
compile(project(":spring-context"))

//数据
compile(project(":spring-jdbc"))

testCompile group: 'junIT', name: 'junit', version: '4.12'

配置数据源和sqlsessionfactory

@configuration
@MapperScan("wyw")
@componentScan("wyw")
public class MybatisConfig {

   @Bean
   public DataSource dataSource(){
      DriverManagerDataSource driverManagerDataSource
            = new DriverManagerDataSource();
      driverManagerDataSource.setDriverclassname("com.mysql.jdbc.Driver");
      driverManagerDataSource.setPassword("root");
      driverManagerDataSource.setUsername("root");
      driverManagerDataSource.setUrl("jdbc:mysql://localhost:3306/task3?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai");
      return driverManagerDataSource;
   }


   @Bean
   @Autowired
   public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource){
      SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
      sqlSessionFactoryBean.setDataSource(dataSource);
      return sqlSessionFactoryBean;
   }
}

  IndexService中打印:

@Slf4j(topic = "e")
@Component
public class IndexService {

   @Autowired
   IndexDao indexDao;

   public void list(){
      List<;map<String, Object>> list = indexDao.list();
      LOG.debug("list:{}",list);
   }
}

   主线程看结果:

public static void main(String[] args) {
   AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();
   ac.register(MybatisConfig.class);
   ac.refresh();

   IndexService service = ac.getBean(IndexService.class);
   service.list();

}

运行:

Spring源码(1)mybatis核心原理

 

==============================

分析核心功能:

在service中调用dao的位置打断点:

Spring源码(1)mybatis核心原理

Spring源码(1)mybatis核心原理

可以看到,  indexDao  是 MapperProxy类型的对象, 其实就是  

InvocationHandler

类型

Spring源码(1)mybatis核心原理

所以,就是 jdk动态代理来实现的。这其实是个结论,这个结论如何产生的呢。。。。

 

==============================

MybatisFactoryBean 很明显是mybatis开发的,不是spring开发的。

由上面的逻辑,就可以假设,脱离spring,也可以单纯的通过mybatis得到一个dao对象

官网上的说法得到对象:

environment environment = null;
Configuration configuration = new Configuration(environment);
configuration.addMapper(IndexDao.class);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
SqlSession sqlSession = sqlSessionFactory.openSession();

IndexDao mapper = sqlSession.getMapper(IndexDao.class);

所以

IndexDao mapper = sqlSession.getMapper(IndexDao.class);

可能是这里得到的对象,也可能是之前行得到的然后这里获取。;;也可能不是。

Spring源码(1)mybatis核心原理

Spring源码(1)mybatis核心原理

Spring源码(1)mybatis核心原理

Spring源码(1)mybatis核心原理

里面有一行:

Spring源码(1)mybatis核心原理

return mapperProxyFactory.newInstance(sqlSession);

这行代码,也说明两种可能,可能就是在这行创建的对象,也可能是之前产生的这里获取。

Spring源码(1)mybatis核心原理

Spring源码(1)mybatis核心原理

return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);

  第一个是类加载器,第二个是接口,第三个是 实现了 innovationhandler接口的类

所以可以看出,就是这里产生的,而不是之前产生然后拿到。

 

=================================

如果要模拟mybatis 

Spring源码(1)mybatis核心原理

实现innovationHandler接口的那个类,哟啊重写invoke方法,里面的参数 Method 就是当前调用的方法。

invoke 方法 的大致思路就是,先根据这个方法得到注解,然后通过注解得到sql语句,(配置文件不考虑),然后连接数据库执行sql,最后返回就ok了。

 

============

细节

Spring源码(1)mybatis核心原理

Spring源码(1)mybatis核心原理

  动态代理底层其实重写了 toString方法,

但是每一个代理对象执行的方法,都要经过 invoke方法,所以在打印的时候可以:

Spring源码(1)mybatis核心原理

 

  

这样子自定义一下就ok了。

 

脚本宝典总结

以上是脚本宝典为你收集整理的Spring源码(1)mybatis核心原理全部内容,希望文章能够帮你解决Spring源码(1)mybatis核心原理所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。