周所周知,SpringBoot可以非常方便的实现数据库的连接访问。只要配置数据库的相关属性,定义对应的Entity以及Repository就可以实现对数据库的增删改查。
properties
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.password=root
spring.datasource.username=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
entity
@Entity
@Getter
@Setter
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
}
repository
@Repository
public interface UserDao extends JpaRepository<User, Integer> {
}
那么SprintBoot是如何实现这些的呢?我们一步一步来看,今天首先来看下SpringBoot是如何自动装载DataSource。
EnableAutoConfiguration
对于@SpringBootApplication这个注解相信大家都不陌生,在启动SpringBoot项目时大都会用到这个注解。它其实是有3个注解组成
- @SpringBootConfiguration: 继承自@Configuration,二者功能也一致,标注当前类是配置类,并会将当前类内声明的一个或多个以@Bean注解标记的方法的实例纳入到spring容器中,并且实例名就是方法名
- @EnableAutoConfiguration: 自动装载配置
- @ComponentScan:开启组件扫描,即自动扫描包路径下的@Component注解进行注册bean实例到 context中
@EnableAutoConfiguration是SpringBoot实现自动装载配置的关键,那么它又是如何实现的呢。先来看下它的源码
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
/**
* Exclude specific auto-configuration classes such that they will never be applied.
* @return the classes to exclude
*/
Class<?>[] exclude() default {};
/**
* Exclude specific auto-configuration class names such that they will never be
* applied.
* @return the class names to exclude
* @since 1.3.0
*/
String[] excludeName() default {};
}
可以看到@EnableAutoConfiguration注解的主要作用是引入了AutoConfigurationImportSelector。那么这个类的作用又是什么呢?
AutoConfigurationImportSelector可以根据@Conditional将满足条件的@Configuration引入到Spring容器中。简单来说就是引入了所有需要自动装载的配置。
AutoConfigurationImportSelector从spring.factories获取需要装载的配置
在spring.factories文件中我们可以看到org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,正式通过引入这个类,SpringBoot才自动装载了DataSource。
DataSourceAutoConfiguration
我们来看下DataSourceAutoConfiguration的具体实现
主要逻辑如下
1.仅当DataSource,EmbeddedDatabaseType存在时配置才生效
2.加载DataSourceProperties,将前缀为spring.datasource的配置项装载到DataSourceProperties
3.引入DataSourcePoolMetadataProvidersConfiguration,提供DataSourcePoolMetadataProvider配置(连接池元数据)
4-1.引入DataSourceInitializationConfiguration,设置DataSourceInitializerPostProcessor
4-2.引入DataSourceInitializerInvoker,用于执行schema-.sql,data-.sql
5-1.当嵌入式数据库(h2,derby)被使用时,引入嵌入式数据库相关的数据源配置
5-2.当数据源支持连接池,引入数据源配置,SpringBoot默认使用Hikari
总结
- SpringBoot通过读取文件Classpath:\META-INF\spring.factories来引入配置
- @EnableAutoConfiguration会获取spring.factories中key为org.springframework.boot.autoconfigure.EnableAutoConfiguration的值
- 通过上述两个步骤,DataSourceAutoConfiguration配置被引入,从而自动装载DataSource