SpringBoot starter 原理分析
简介
SpringBoot starter 是SpringBoot提供自动装配的组件,starter的引入大大的减少了常规spring项目的xml配置,减少了由于配置书写错误,配置缺失等问题引起的项目启动异常。
自动装配原理
通过添加所需的starter到pom中 maven自动将所需的间接依赖添加到项目中,我们以spring-boot-starter-actuator为例分析下依赖关系,在pom中添加如下依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
进入spring-boot-starter-actuator依赖查看内部关系会发现spring-boot-actuator-autoconfigure该类会自动装配bean
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.2.6.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator-autoconfigure</artifactId>
<version>2.2.6.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-core</artifactId>
<version>1.3.6</version>
<scope>compile</scope>
</dependency>
</dependencies>
通过pom文件里我们发现了spring-boot-actuator-autoconfigure 接下来我们查看下自动装配的具体代码,由于actuator是监控模块,内置很多监控组件我们只拿DataSourceHealthContributorAutoConfiguration进行分析
@Configuration(
proxyBeanMethods = false
)
@ConditionalOnClass({JdbcTemplate.class, AbstractRoutingDataSource.class})
@ConditionalOnBean({DataSource.class})
@ConditionalOnEnabledHealthIndicator("db")
@AutoConfigureAfter({DataSourceAutoConfiguration.class})
public class DataSourceHealthContributorAutoConfiguration extends CompositeHealthContributorConfiguration<AbstractHealthIndicator, DataSource> implements InitializingBean {
private final Collection<DataSourcePoolMetadataProvider> metadataProviders;
private DataSourcePoolMetadataProvider poolMetadataProvider;
public DataSourceHealthContributorAutoConfiguration(Map<String, DataSource> dataSources, ObjectProvider<DataSourcePoolMetadataProvider> metadataProviders) {
this.metadataProviders = (Collection)metadataProviders.orderedStream().collect(Collectors.toList());
}
public void afterPropertiesSet() throws Exception {
this.poolMetadataProvider = new CompositeDataSourcePoolMetadataProvider(this.metadataProviders);
}
@Bean
@ConditionalOnMissingBean(
name = {"dbHealthIndicator", "dbHealthContributor"}
)
public HealthContributor dbHealthContributor(Map<String, DataSource> dataSources) {
return (HealthContributor)this.createContributor(dataSources);
}
protected AbstractHealthIndicator createIndicator(DataSource source) {
return (AbstractHealthIndicator)(source instanceof AbstractRoutingDataSource ? new DataSourceHealthContributorAutoConfiguration.RoutingDataSourceHealthIndicator() : new DataSourceHealthIndicator(source, this.getValidationQuery(source)));
}
private String getValidationQuery(DataSource source) {
DataSourcePoolMetadata poolMetadata = this.poolMetadataProvider.getDataSourcePoolMetadata(source);
return poolMetadata != null ? poolMetadata.getValidationQuery() : null;
}
static class RoutingDataSourceHealthIndicator extends AbstractHealthIndicator {
RoutingDataSourceHealthIndicator() {
}
protected void doHealthCheck(Builder builder) throws Exception {
builder.unknown().withDetail("routing", true);
}
}
}
从代码中我们能看到很多熟悉的注解例如@Configuration通过该注解将会初始化bean到容器中,至此自动装配完成
自动装配中注解介绍
@ConditionalOnBean,仅在当前上下文中存在某个bean时,才会实例化这个Bean。
@ConditionalOnClass,某个class位于类路径上,才会实例化这个Bean。
@ConditionalOnExpression,当表达式为true的时候,才会实例化这个Bean。
@ConditionalOnMissingBean,仅在当前上下文中不存在某个bean时,才会实例化这个Bean。
@ConditionalOnMissingClass,某个class在类路径上不存在的时候,才会实例化这个Bean。
@ConditionalOnNotWebApplication,不是web应用时才会实例化这个Bean。
@AutoConfigureAfter,在某个bean完成自动配置后实例化这个bean。
@AutoConfigureBefore,在某个bean完成自动配置前实例化这个bean。
文章同步更新到公众号 二线程序猿 欢迎扫码关注