SpringBoot 源码解析 (九)

您所在的位置:网站首页 plsql连接数据库提示无监听 SpringBoot 源码解析 (九)

SpringBoot 源码解析 (九)

#SpringBoot 源码解析 (九)| 来源: 网络整理| 查看: 265

首页 > > 程序设计 > Java技术 > SpringBoot 源码解析 (九)----- Spring Boot的…

2019-11-26 16:08:11来源:博客园 阅读 ()

新老客户大回馈,云服务器低至5折 SpringBoot 源码解析 (九)----- Spring Boot的核心能力 - 整合Mybatis

本篇我们在SpringBoot中整合Mybatis这个orm框架,毕竟分析一下其自动配置的源码,我们先来回顾一下以前Spring中是如何整合Mybatis的,大家可以看看我这篇文章Mybaits 源码解析 (十)----- Spring-Mybatis框架使用与源码解析 

Spring-Mybatis使用 添加maven依赖 org.springframework spring-jdbc 4.3.8.RELEASE org.mybatis mybatis-spring 1.3.2 在src/main/resources下添加mybatis-config.xml文件 DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> 在src/main/resources/mapper路径下添加User.xml DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> SELECT * FROM USER WHERE id = #{id} 在src/main/resources/路径下添加beans.xml 注解的方式 以上分析都是在spring的XML配置文件applicationContext.xml进行配置的,mybatis-spring也提供了基于注解的方式来配置sqlSessionFactory和Mapper接口。 sqlSessionFactory主要是在@Configuration注解的配置类中使用@Bean注解的名为sqlSessionFactory的方法来配置; Mapper接口主要是通过在@Configuration注解的配置类中结合@MapperScan注解来指定需要扫描获取mapper接口的包。 @Configuration @MapperScan("com.chenhao.mapper") public class AppConfig { @Bean public DataSource dataSource() { return new EmbeddedDatabaseBuilder() .addScript("schema.sql") .build(); } @Bean public DataSourceTransactionManager transactionManager() { return new DataSourceTransactionManager(dataSource()); } @Bean public SqlSessionFactory sqlSessionFactory() throws Exception { //创建SqlSessionFactoryBean对象 SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean(); //设置数据源 sessionFactory.setDataSource(dataSource()); //设置Mapper.xml路径 sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml")); // 设置MyBatis分页插件 PageInterceptor pageInterceptor = new PageInterceptor(); Properties properties = new Properties(); properties.setProperty("helperDialect", "mysql"); pageInterceptor.setProperties(properties); sessionFactory.setPlugins(new Interceptor[]{pageInterceptor}); return sessionFactory.getObject(); } }

最核心的有两点:

创建一个SqlSessionFactoryBean,并设置数据源和Mapper.xml路径,其中会解析Mapper.xml文件,最后通过getObject()返回一个SqlSessionFactory 注入Spring容器中 通过@MapperScan扫描所有Mapper接口,扫描过程会将Mapper接口生成MapperFactoryBean这个特殊的Bean,并且在其getObject()通过SqlSession().getMapper(this.mapperInterface)生成每个mapper接口真实的代理类

MapperFactoryBean

//最终注入Spring容器的就是这里的返回对象 public T getObject() throws Exception { //获取父类setSqlSessionFactory方法中创建的SqlSessionTemplate //通过SqlSessionTemplate获取mapperInterface的代理类 //我们例子中就是通过SqlSessionTemplate获取com.chenhao.mapper.UserMapper的代理类 //获取到Mapper接口的代理类后,就把这个Mapper的代理类对象注入Spring容器 return this.getSqlSession().getMapper(this.mapperInterface); }

接下来我们看看SpringBoot是如何引入Mybatis的

SpringBoot引入Mybatis 添加mybatis依赖 com.alibaba druid 1.1.9 org.mybatis.spring.boot mybatis-spring-boot-starter 1.3.2 全局配置文件中配置数据源和mybatis属性 spring: datasource: url: jdbc:mysql:///springboot username: root password: admin type: com.alibaba.druid.pool.DruidDataSource initialSize: 5 minIdle: 5 maxActive: 20 mybatis: config-location: classpath:mybatis/mybatis-config.xml mapper-locations: classpath:mybatis/mapper/*.xml type-aliases-package: org.com.cay.spring.boot.entity 加入Mapper扫描注解@MapperScan @SpringBootApplication @EnableScheduling @ServletComponentScan @MapperScan("com.supplychain.app.mapper") public class Application { public static void main(String[] args) { TimeZone.setDefault(TimeZone.getTimeZone("GMT+8")); System.setProperty("user.timezone", "GMT+8"); SpringApplication.run(Application.class, args); } } 源码解析 mybatis-spring-boot-starter

我们看到mybatis-spring-boot-starter实际上引入了jdbc的场景启动器,这一块我们上一篇文章已经分析过了,还引入了mybatis-spring的依赖,最终还引入了mybatis-spring-boot-autoconfigure这个依赖,其实mybatis-spring-boot-starter只是引入各种需要的依赖,最核心的代码是在引入的mybatis-spring-boot-autoconfigure这个项目当中,我们来看看这个项目

我们看到mybatis-spring-boot-autoconfigure也像spring-boot-autoconfigure一样配置了spring.factories这个配置文件,并且在配置文件中配置了MybatisAutoConfiguration这个自动配置类,我们知道SpringBoot启动时会获取所有spring.factories配置文件中的自动配置类并且进行解析其中的Bean,那么我们就来看看MybatisAutoConfiguration这个自动配置类做了啥?

MybatisAutoConfiguration 1 @org.springframework.context.annotation.Configuration 2 @ConditionalOnClass({ SqlSessionFactory.class, SqlSessionFactoryBean.class }) 3 @ConditionalOnBean(DataSource.class) 4 //引入MybatisProperties配置类 5 @EnableConfigurationProperties(MybatisProperties.class) 6 @AutoConfigureAfter(DataSourceAutoConfiguration.class) 7 public class MybatisAutoConfiguration { 8 9 private final MybatisProperties properties; 10 11 private final Interceptor[] interceptors; 12 13 private final ResourceLoader resourceLoader; 14 15 private final DatabaseIdProvider databaseIdProvider; 16 17 private final List configurationCustomizers; 18 19 public MybatisAutoConfiguration(MybatisProperties properties, 20 ObjectProvider interceptorsProvider, 21 ResourceLoader resourceLoader, 22 ObjectProvider databaseIdProvider, 23 ObjectProvider configurationCustomizersProvider) { 24 this.properties = properties; 25 this.interceptors = interceptorsProvider.getIfAvailable(); 26 this.resourceLoader = resourceLoader; 27 this.databaseIdProvider = databaseIdProvider.getIfAvailable(); 28 this.configurationCustomizers = configurationCustomizersProvider.getIfAvailable(); 29 } 30 31 @Bean 32 @ConditionalOnMissingBean 33 //往Spring容器中注入SqlSessionFactory对象 34 //并且设置数据源、MapperLocations(Mapper.xml路径)等 35 public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception { 36 SqlSessionFactoryBean factory = new SqlSessionFactoryBean(); 37 factory.setDataSource(dataSource); 38 factory.setVfs(SpringBootVFS.class); 39 if (StringUtils.hasText(this.properties.getConfigLocation())) { 40 factory.setConfigLocation(this.resourceLoader.getResource(this.properties.getConfigLocation())); 41 } 42 Configuration configuration = this.properties.getConfiguration(); 43 if (configuration == null && !StringUtils.hasText(this.properties.getConfigLocation())) { 44 configuration = new Configuration(); 45 } 46 if (configuration != null && !CollectionUtils.isEmpty(this.configurationCustomizers)) { 47 for (ConfigurationCustomizer customizer : this.configurationCustomizers) { 48 customizer.customize(configuration); 49 } 50 } 51 factory.setConfiguration(configuration); 52 if (this.properties.getConfigurationProperties() != null) { 53 factory.setConfigurationProperties(this.properties.getConfigurationProperties()); 54 } 55 if (!ObjectUtils.isEmpty(this.interceptors)) { 56 factory.setPlugins(this.interceptors); 57 } 58 if (this.databaseIdProvider != null) { 59 factory.setDatabaseIdProvider(this.databaseIdProvider); 60 } 61 if (StringUtils.hasLength(this.properties.getTypeAliasesPackage())) { 62 factory.setTypeAliasesPackage(this.properties.getTypeAliasesPackage()); 63 } 64 if (StringUtils.hasLength(this.properties.getTypeHandlersPackage())) { 65 factory.setTypeHandlersPackage(this.properties.getTypeHandlersPackage()); 66 } 67 if (!ObjectUtils.isEmpty(this.properties.resolveMapperLocations())) { 68 factory.setMapperLocations(this.properties.resolveMapperLocations()); 69 } 70 //获取SqlSessionFactoryBean的getObject()中的对象注入Spring容器,也就是SqlSessionFactory对象 71 return factory.getObject(); 72 } 73 74 @Bean 75 @ConditionalOnMissingBean 76 //往Spring容器中注入SqlSessionTemplate对象 77 public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) { 78 ExecutorType executorType = this.properties.getExecutorType(); 79 if (executorType != null) { 80 return new SqlSessionTemplate(sqlSessionFactory, executorType); 81 } else { 82 return new SqlSessionTemplate(sqlSessionFactory); 83 } 84 } 85 86 //other code... 87 }

在自动配置的时候会导入一个Properties配置类MybatisProperties,咱们来看一下

@ConfigurationProperties(prefix = MybatisProperties.MYBATIS_PREFIX) public class MybatisProperties { public static final String MYBATIS_PREFIX = "mybatis"; /** * Location of MyBatis xml config file. */ private String configLocation; /** * Locations of MyBatis mapper files. */ private String[] mapperLocations; /** * Packages to search type aliases. (Package delimiters are ",; \t\n") */ private String typeAliasesPackage; /** * Packages to search for type handlers. (Package delimiters are ",; \t\n") */ private String typeHandlersPackage; /** * Indicates whether perform presence check of the MyBatis xml config file. */ private boolean checkConfigLocation = false; /** * Execution mode for {@link org.mybatis.spring.SqlSessionTemplate}. */ private ExecutorType executorType; /** * Externalized properties for MyBatis configuration. */ private Properties configurationProperties; /** * A Configuration object for customize default settings. If {@link #configLocation} * is specified, this property is not used. */ @NestedConfigurationProperty private Configuration configuration; //other code... }

?该Properties配置类作用主要用于与yml/properties中以mybatis开头的属性进行一一对应,如下

mybatis: config-location: classpath:mybatis/mybatis-config.xml mapper-locations: classpath:mybatis/mapper/*.xml type-aliases-package: org.com.cay.spring.boot.entity ?在MybatisAutoConfiguration自动配置类中,SpringBoot默认自动配置了两个Bean,分别是SqlSessionFactory和SqlSessionTemplate。我们看到上面代码中第71行,其实是返回的factory.getObject();,也就是注入Spring容器中的是SqlSessionFactory对象,SqlSessionFactory主要是将Properties配置类中的属性赋值到SqlSessionFactoryBean中,类似以前xml中配置的SqlSessionFactory ...

另外一个Bean为SqlSessionTemplate,通过SqlSessionFactory来生成SqlSession代理类:

public class SqlSessionTemplate implements SqlSession, DisposableBean { private final SqlSessionFactory sqlSessionFactory; private final ExecutorType executorType; private final SqlSession sqlSessionProxy; private final PersistenceExceptionTranslator exceptionTranslator; //other code... public SqlSessionTemplate(SqlSessionFactory sqlSessionFactory, ExecutorType executorType, PersistenceExceptionTranslator exceptionTranslator) { notNull(sqlSessionFactory, "Property 'sqlSessionFactory' is required"); notNull(executorType, "Property 'executorType' is required"); this.sqlSessionFactory = sqlSessionFactory; this.executorType = executorType; this.exceptionTranslator = exceptionTranslator; //生成SqlSessioin代理类 this.sqlSessionProxy = (SqlSession) newProxyInstance( SqlSessionFactory.class.getClassLoader(), new Class[] { SqlSession.class }, new SqlSessionInterceptor()); } }

而@MapperScan注解是和Spring整合Mybatis的使用是一样的,都是在配置类上指定Mapper接口的路径,大家可以看一下我以前的一篇文章Mybaits 源码解析 (十一)----- @MapperScan将Mapper接口生成代理注入到Spring-静态代理和动态代理结合使用

日常求赞

好了各位,以上就是这篇文章的全部内容了,能看到这里的人呀,都是人才。

如果这个文章写得还不错,觉得学到了一点东西的话 求点赞?? 对我来说真的 非常有用!!!

创作不易,各位的支持和认可,就是我创作的最大动力,我们下篇文章见!

 

原文链接:https://www.cnblogs.com/java-chen-hao/p/11849869.html如有疑问请与原作者联系

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:[email protected] 特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:【设计模式】单例模式的八种姿态写法分析

下一篇:Java 复习笔记7 - 集合框架

相关文章 springboot2配置JavaMelody与springMVC配置JavaMelody 2020-06-11 JVM常见面试题解析 2020-06-11 SpringBoot 2.3 整合最新版 ShardingJdbc + Druid + MyBatis 2020-06-11 掌握SpringBoot-2.3的容器探针:实战篇 2020-06-11 nacos~配置中心功能~springboot的支持 2020-06-10

IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设

网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源

网站联盟: 联盟新闻 联盟介绍 联盟点评 网赚技巧

行业资讯: 搜索引擎 网络游戏 电子商务 广告传媒

网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它

服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护

软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷

网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash

程序设计: Java技术 C/C++ VB delphi

网络知识: 网络协议 网络安全 网络管理 组网方案 Cisco技术

操作系统: Win2000 WinXP Win2003 Mac OS Linux FreeBSD



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3