spring boot 整合mybtis 为例源码分析

 

1、springboot项目最核心的就是自动加载配置,该功能则依赖的是一个注解@SpringBootApplication中的@EnableAutoConfiguration

2、EnableAutoConfiguration主要是通过AutoConfigurationImportSelector类来加载

  以mybatis为例,*selector通过反射加载spring.factories中指定的java类,也就是加载MybatisAutoConfiguration类(该类有Configuration注解,属于配置类)

  

  

  

复制代码

 16 package org.mybatis.spring.boot.autoconfigure; 60 重点:SqlSessionFactory 和 SqlSessionTemplate 两个类
 61 /**
 62  * {@link EnableAutoConfiguration Auto-Configuration} for Mybatis. Contributes a
 63  * {@link SqlSessionFactory} and a {@link SqlSessionTemplate}.
 64  *
 65  * If {@link org.mybatis.spring.annotation.MapperScan} is used, or a
 66  * configuration file is specified as a property, those will be considered,
 67  * otherwise this auto-configuration will attempt to register mappers based on
 68  * the interface definitions in or under the root auto-configuration package.
 69  *
 70  * @author Eddú Meléndez
 71  * @author Josh Long
 72  * @author Kazuki Shimizu
 73  * @author Eduardo Macarrón
 74  */
 75 @org.springframework.context.annotation.Configuration
 76 @ConditionalOnClass({ SqlSessionFactory.class, SqlSessionFactoryBean.class })
 77 @ConditionalOnBean(DataSource.class)
 78 @EnableConfigurationProperties(MybatisProperties.class)
 79 @AutoConfigureAfter(DataSourceAutoConfiguration.class)
 80 public class MybatisAutoConfiguration {
 81 
 82   private static final Logger logger = LoggerFactory.getLogger(MybatisAutoConfiguration.class);
 83  //与mybatis配置文件对应
 84   private final MybatisProperties properties;
 85 
 86   private final Interceptor[] interceptors;
 87 
 88   private final ResourceLoader resourceLoader;
 89 
 90   private final DatabaseIdProvider databaseIdProvider;
 91 
 92   private final List<ConfigurationCustomizer> configurationCustomizers;
 93 
 94   public MybatisAutoConfiguration(MybatisProperties properties,
 95                                   ObjectProvider<Interceptor[]> interceptorsProvider,
 96                                   ResourceLoader resourceLoader,
 97                                   ObjectProvider<DatabaseIdProvider> databaseIdProvider,
 98                                   ObjectProvider<List<ConfigurationCustomizer>> configurationCustomizersProvider) {
 99     this.properties = properties;
100     this.interceptors = interceptorsProvider.getIfAvailable();
101     this.resourceLoader = resourceLoader;
102     this.databaseIdProvider = databaseIdProvider.getIfAvailable();
103     this.configurationCustomizers = configurationCustomizersProvider.getIfAvailable();
104   }
105  //postConstruct作用是在创建类的时候先调用,  校验配置文件是否存在
106   @PostConstruct
107   public void checkConfigFileExists() {
108     if (this.properties.isCheckConfigLocation() && StringUtils.hasText(this.properties.getConfigLocation())) {
109       Resource resource = this.resourceLoader.getResource(this.properties.getConfigLocation());
110       Assert.state(resource.exists(), "Cannot find config location: " + resource
111           + " (please add config file or check your Mybatis configuration)");
112     }
113   }
114   //conditionalOnMissingBean作用:在没有类的时候调用,创建sqlsessionFactory  sqlsessionfactory最主要的是创建并保存了Configuration类
115   @Bean
116   @ConditionalOnMissingBean
117   public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
118     SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
119     factory.setDataSource(dataSource);
120     factory.setVfs(SpringBootVFS.class);
121     if (StringUtils.hasText(this.properties.getConfigLocation())) {
122       factory.setConfigLocation(this.resourceLoader.getResource(this.properties.getConfigLocation()));
123     }
124     Configuration configuration = this.properties.getConfiguration();
125     if (configuration == null && !StringUtils.hasText(this.properties.getConfigLocation())) {
126       configuration = new Configuration();
127     }
128     if (configuration != null && !CollectionUtils.isEmpty(this.configurationCustomizers)) {
129       for (ConfigurationCustomizer customizer : this.configurationCustomizers) {
130         customizer.customize(configuration);
131       }
132     }
133     factory.setConfiguration(configuration);
134     if (this.properties.getConfigurationProperties() != null) {
135       factory.setConfigurationProperties(this.properties.getConfigurationProperties());
136     }
137     if (!ObjectUtils.isEmpty(this.interceptors)) {
138       factory.setPlugins(this.interceptors);
139     }
140     if (this.databaseIdProvider != null) {
141       factory.setDatabaseIdProvider(this.databaseIdProvider);
142     }
143     if (StringUtils.hasLength(this.properties.getTypeAliasesPackage())) {
144       factory.setTypeAliasesPackage(this.properties.getTypeAliasesPackage());
145     }
146     if (StringUtils.hasLength(this.properties.getTypeHandlersPackage())) {
147       factory.setTypeHandlersPackage(this.properties.getTypeHandlersPackage());
148     }
149     if (!ObjectUtils.isEmpty(this.properties.resolveMapperLocations())) {
150       factory.setMapperLocations(this.properties.resolveMapperLocations());
151     }
152 
153     return factory.getObject();
154   }
155 
156   @Bean
157   @ConditionalOnMissingBean
158   public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
159     ExecutorType executorType = this.properties.getExecutorType();
160     if (executorType != null) {
161       return new SqlSessionTemplate(sqlSessionFactory, executorType);
162     } else {
163       return new SqlSessionTemplate(sqlSessionFactory);
164     }
165   }
238 }

复制代码

3、MybatisAutoConfiguration:

①类中有个MybatisProperties类,该类对应的是mybatis的配置文件

②类中有个sqlSessionFactory方法,作用是创建SqlSessionFactory类、Configuration类(mybatis最主要的类,保存着与mybatis相关的东西)

③SelSessionTemplate,作用是与mapperProoxy代理类有关

4、关注下Configuration中的MapperRegister类,该类是创建dao(mapper的代理类),后续具体执行dao查询操作的都是基于该类的

 

下边是springboot项目启动栈信息:

1、springboot启动调用SpringApplication的静态方法run

  

2、进入run方法:先进行springboot相关初始化

  

3、进入refreshContext方法:初始化springboot的上下文

4、进入refresh方法(AbstractApplicationContext)

5、通过beanfactory实力各种bean

。。。。

6、在ConfigurationClassBeanDefinitionReader类来注册加载所有的spring.facotrys中指定的类

7、最后到MybatisAutoConfiguration的registerBeanDefinition方法中,并且在new classPathMapperScanner对象中会配置environment

8、通过ClassPathMapperScanner扫描mapper文件

9、进入scanner的doscan方法(其实调用的是父类的doScan方法)

 10、进入父类ClassPathBeanDefinitionScanner类的doScan方法(其中basePackages就是application的包路径,这个包路径其实就是@springBootApplication注解中的一个主机ComponentScan类得到的)

11、在findCandidateComponents中返回Set集合(mapper类的集合)

。。。。

12、当springboot调用getBean方法是才是真正创建类的时候

13、最终到创建MybatisAutoConfiguration类了

在创建之前会调用checkConfigFileExists方法(因为方法上有@PostConstruct),校验mybatis配置文件是否存在

14、以上校验完之后,到注入属性

  注入的时候通过beanname调用getbean方法来获取一个bean

15、在doGetBean方法中通过getSigngton(name)方法来获取已经注册过得bean,注册的bean都存在DefaultSingletonBeanRegister类的SingtonObjects的map对象中

 

另外该map对象中还存了这些bean:

  SqlsessionFactory:

  

  与事务相关的bean:

  

  环境变量:

  

  数据源配置bean:

  

  sqlSessionTemplate:

  

  等等。。。。

16、getbean最终通过MapperFactoryBean中的getObject方法来获取,其中getSqlSession方法返回的是SqlSessionTemplate,也就是getMapper调用的是SQLSessionTemplate中

的方法

17、进去到SqlSessionTemplage,getMapper实际上是从Configuration对象中类获取mapper

18、进去到Configuration中,getMapper实际上是从MapperRegister对象中获取的

19、进入到MapperRegister中,getMapper是从knownMappers 的map对象中来获取的,获取到mapperProxyFactory后,mapper工厂通过newInstance来创建一个mapperProxy

代理对象

 

 

20、这个mapperProxy就是在使用userdao的时候的代理类

 

 

 

 

参考博文:https://www.cnblogs.com/nxzblogs/p/10484281.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Spring整合Mybatis源码分析可以分为以下几个步骤: 1. 创建Spring容器并加载配置文件。在Spring Boot中,可以通过@SpringBootApplication注解来创建Spring容器,并在配置文件中配置Mybatis相关的属性。 2. 创建Mybatis的SqlSessionFactory。Spring Boot会自动配置Mybatis的SqlSessionFactory,通过读取配置文件中的数据源信息和Mybatis的配置信息,创建SqlSessionFactory对象。 3. 注册Mybatis的Mapper接口。Spring Boot会自动扫描项目中的Mapper接口,并将其注册到Spring容器中。 4. 创建Mapper代理对象。Spring Boot使用Mybatis的MapperFactoryBean来创建Mapper接口的代理对象。在创建代理对象时,会使用SqlSessionFactory来创建SqlSession,并将SqlSession注入到Mapper接口中。 5. 使用Mapper代理对象进行数据库操作。通过调用Mapper接口的方法,可以实现对数据库的增删改查操作。 整个过程中,Spring Boot通过自动配置和注解扫描的方式,简化了Spring整合Mybatis的配置和使用过程,使得开发者可以更方便地使用Mybatis进行数据库操作。\[1\]\[2\]\[3\] #### 引用[.reference_title] - *1* [SpringBoot整合Mybatis源码解析](https://blog.csdn.net/u013521882/article/details/120624374)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [Spring-Mybatis整合源码分析](https://blog.csdn.net/qq_42651904/article/details/111059652)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [Spring源码解析之整合Mybatis](https://blog.csdn.net/heroqiang/article/details/79135500)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

执于代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值