接触mybatis已经好几年了,一直以来,都只知道使用,但是对里面的原理以及其具体是怎么加载的,并不清楚,今天特意花了一上午的时间,研究了下它的源码。下面使用的是springboot+mybatis+tomcat-jdbc(springboot2.0以前默认的数据库连接池是tomcat-jdbc,2.0以后默认的连接池是hikari,本人项目引用的是springboot1.5.3)
一、springboot的加载机制:
要想搞明白mybatis是怎么被加载到springboot中并且默认使用tomcat-jdbc的,那首先要了解springboot的加载机制。
每一个springboot的项目,在Application类上都有一个SpringBootApplication注解,springboot项目在启动的时候,会自动去读取这个注解,进入这个注解,可以看到,它又包含了一下注解:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
每一个springboot项目里面,我们经常需要用到@Configuration以及@bean/@Service等注解,这些注解在项目中能够被发现,主要要归功于上面所列出来的@ComponentScan注解,ComponentScan这个注解的作用是扫描项目,发现项目中的注解,并且归于springboot来管理。
但是非本项目外的其他引用依赖包中的注解发现就需要@EnableAutoConfiguration来发辉功效了。而在这个注解里面,又导入了EnableAutoConfigurationImportSelector类,此类继承AutoConfigurationImportSelector,在这个里面的getCandidateConfigurations方法,会将MATE-INF/spring.factories文件中的org.springframework.boot.autoconfigure.EnableAutoConfiguration的key对应的value全部加载到spring容器中,源码如下:
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata,
AnnotationAttributes attributes) {
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(
getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());
Assert.notEmpty(configurations,
"No auto configuration classes found in META-INF/spring.factories. If you "
+ "are using a custom packaging, make sure that file is correct.");
return configurations;
}
这样,springboot就能够将本项目以及本项目引入的第三方JAR包中的配置注解以及bean全部加载到容器中了。
二、springboot默认加载tomcat-jdbc的源码分析
我们都知道,在spring2.0以前,springboot默认使用的数据库连接池是tomcat-jdbc,但是它具体是怎么配置以及使用的,下面是对它的源码分析:
在springboot的spring.factories中,有一个DataSourceAutoConfiguration,说明,在springboot项目启动的时候,便会去加载这个配置类,在这个类里面,有几个条件注解,其中有一个是导入springboot默认集成的几个数据连接池的:
@Configuration
@Conditional(PooledDataSourceCondition.class)
@ConditionalOnMissingBean({
DataSource.class, XADataSource.class })
@Import({
DataSourceConfiguration.Tomcat.class, DataSourceConfiguration.Hikari.class,
DataSourceConfiguration.Dbcp.class, DataSourceConfiguration.Dbcp2.class,
DataSourceConfiguration.Generic.class })
@SuppressWarnings("deprecation")
protected static class PooledDataSourceConfiguration {
}
在PooledDataSourceCondition的类中的getDataSourceClassLoader方法:
private ClassLoader getDataSou