SpringBoot自动配置原理
2021-04-02 03:25
标签:运行 configure tar loading pack gets 针对 final gap 在SpringBoot启动主配置类时,@SpringBootApplication 注解发挥作用进行自动配置。 @SpringBootApplication 注解中,实际发挥作用的是 @EnableAutoConfiguration 注解。 而在@EnableAutoConfiguration 中,导入了一个自动配置选择器类 AutoConfigurationImportSelector。 在AutoConfigurationImportSelector 类中有一个selectImports 方法, getAutoConfigurationEntry() 获取配置信息条目。 这个方法里面的 getCandidateConfigurations() 执行的是获取候选的配置。 按住Ctrl,继续点击追查 getCandidateConfigurations() 方法,可以看到 这时候看到一个字符串,似乎越来越接近真相了。 还有一句很关键的语句。 SpringFactoriesLoader ? 配置要在这里获取? 看来还要继续深入。 到这里可以确定是要读取在 META-INF/spring.factories 这个配置文件,这时候,我们可以去看 jar 包里的这个配置文件 名为 or.spingframework. borin-booto atonfigre.2.REEASE 的 jar 包下,有这样一个 spring.factories 配置文件。 EnableAutoConfiguration 属性下的值所代表的配置自动都加入到容器中,不再需要我们像刚学习 Spring 时, 在 DataSourceProperties.class 中,我们看到了熟悉的属性。 因此,我们可以在项目中的 application.properties 中配置相关属性。 总结: xxxxAutoConfigurartion:自动配置类;给容器中添加组件 对于想要自定义配置,或者是需要自行配置的相关属性,可以再 xxx.properties 文件中配置修改。 在项目中的 application.properties 中配置 运行主程序,控制台会输出一个自动配置的报告。 SpringBoot 2.0 + 使用的 DataSource 数据源 为 : com.zaxxer.hikari.HikariDataSource 1.0 + : 版本为 : 默认是用org.apache.tomcat.jdbc.pool.DataSource作为数据源。 HikariDataSource 的优点:(来源网络) 字节码精简 :优化代码,直到编译后的字节码最少,这样,CPU缓存可以加载更多的程序代码; 优化代理和拦截器:减少代码,例如HikariCP的Statement proxy只有100行代码,只有BoneCP(另一数据连接池)的十分之一; 自定义数组类型(FastStatementList)代替ArrayList:避免每次get()调用都要进行range check,避免调用remove()时的从头到尾的扫描; 自定义集合类型(ConcurrentBag):提高并发读写的效率; 其他针对BoneCP缺陷的优化,比如对于耗时超过一个CPU时间片的方法调用的研究(但没说具体怎么优化)。 现有连接池性能比较 :hikari>druid>tomcat-jdbc>dbcp>c3p0 SpringBoot自动配置原理 标签:运行 configure tar loading pack gets 针对 final gap 原文地址:https://www.cnblogs.com/l1ng14/p/13472692.htmlSpringBoot自动配置原理
@SpringBootApplication //主程序自动配置
public class SpringBoot02ConfigApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBoot02ConfigApplication.class, args);
}
}
@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 {
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class}) //导入自动配置选择器
public @interface EnableAutoConfiguration {
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!this.isEnabled(annotationMetadata)) {
return NO_IMPORTS;
} else {
AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry
= this.getAutoConfigurationEntry(annotationMetadata); //获取配置信息条目
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
}
protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry
(AnnotationMetadata annotationMetadata) {
if (!this.isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
} else {
AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
List
protected List
"No auto configuration classes found in META-INF/spring.factories.
If you are using a custom packaging, make sure that file is correct."
List
org.springframework.boot.autoconfigure.EnableAutoConfiguration=
在 xml 配置文件中一个个去配置。极大地提高了开发效率。下面以分析自动配置 DataSourceAutoConfiguration(数据源) 为例解释自动配置原理:
@Configuration(
proxyBeanMethods = false
) //注解表明这是一个配置类,同时关闭 proxyBeanMethods ,表示这个配置类不再被代理,
//相当于用 final 修饰,不能在通过 @Bean来调用该配置类
@ConditionalOnClass({DataSource.class, EmbeddedDatabaseType.class})
//判断当前项目是否有数据源类,有则配置生效,查看DataSource.class源码可知是用于获取数据库连接 On表示判断是都包含
@ConditionalOnMissingBean(
type = {"io.r2dbc.spi.ConnectionFactory"}
) //判断当前项目是否不包括这些Bean OnMissing表示判断是否不包含
@EnableConfigurationProperties({DataSourceProperties.class})///启动指定类的ConfigurationProperties功能;
//将配置文件中对应的值和DataSourceProperties绑定起来;并把DataSourceProperties加入到ioc容器中
@Import({DataSourcePoolMetadataProvidersConfiguration.class, DataSourceInitializationConfiguration.class})
public class DataSourceAutoConfiguration {
@ConfigurationProperties(
prefix = "spring.datasource"
) //从配置文件获取对应的属性值,进行绑定
public class DataSourceProperties implements BeanClassLoaderAware, InitializingBean {
private ClassLoader classLoader;
private String name;
private boolean generateUniqueName = true;
private Class extends DataSource> type;
private String driverClassName;
private String url;
private String username;
private String password;
...
spring.datasource.driver-class-name= # Fully qualified name of the JDBC driver.
# Auto-detected based on the URL by default. 驱动名
spring.datasource.url= # JDBC url of the database. 连接需要的url
spring.datasource.username= # Login user of the database. 用户名
spring.datasource.password= # Login password of the database. 密码口令
1)、SpringBoot启动会加载大量的自动配置类
2)、我们看我们需要的功能有没有SpringBoot默认写好的自动配置类;
3)、我们再来看这个自动配置类中到底配置了哪些组件;(只要我们要用的组件有,我们就不需要再来配置了)
4)、给容器中自动配置类添加组件的时候,会从properties类中获取某些属性。我们就可以在配置文件中指定这些属性的值;既然自动配置需要一定条件判断才能生效,那么怎么查看 SpringBoot 已经帮助我们配置了哪些类呢?
2020.08.15 更新