springboot自動配置原理和啟動流程
springboot enable註解自動配置流程
自動配置流程
核心只有4步
@EnableCircuitBreaker
@MapperScan("com.github.chengzhx76.service.order.dao")
public class OrderServiceApplication {
public static void main(String[] args) {
SpringApplication.run(OrderServiceApplication.class, args);
}
}
1、@Enable***一般是@import註解的簡寫,@import是用來匯入某個bean到spring容器的
@Import(EnableCircuitBreakerImportSelector.class)
public @interface EnableCircuitBreaker {
}
2、selector根據條件選擇需要匯入的配置類。
selector是用來匯入meta-inf/spring.factories配置的,繼承SpringFactoryImportSelector
@Order(Ordered.LOWEST_PRECEDENCE - 100)
public class EnableCircuitBreakerImportSelector extends
SpringFactoryImportSelector<EnableCircuitBreaker> {
@Override
protected boolean isEnabled() {
return new RelaxedPropertyResolver(getEnvironment()).getProperty(
"spring.cloud.circuit.breaker.enabled", Boolean.class, Boolean.TRUE);
}
}
3、SpringFactoriesLoader載入spring.factories配置對應的bean
selector通過父類的selectImports呼叫SpringFactoriesLoader載入對應的spring.factories類註冊到beandefinition registry 容器實現ioc
@Override
public String[] selectImports(AnnotationMetadata metadata) {
if (!isEnabled()) {
return new String[0];
}
AnnotationAttributes attributes = AnnotationAttributes.fromMap(
metadata.getAnnotationAttributes(this.annotationClass.getName(), true));
Assert.notNull(attributes, "No " + getSimpleName() + " attributes found. Is "
+ metadata.getClassName() + " annotated with @" + getSimpleName() + "?");
// Find all possible auto configuration classes, filtering duplicates
List<String> factories = new ArrayList<>(new LinkedHashSet<>(SpringFactoriesLoader
.loadFactoryNames(this.annotationClass, this.beanClassLoader)));
if (factories.isEmpty() && !hasDefaultFactory()) {
throw new IllegalStateException("Annotation @" + getSimpleName()
+ " found, but there are no implementations. Did you forget to include a starter?");
}
if (factories.size() > 1) {
// there should only ever be one DiscoveryClient, but there might be more than
// one factory
log.warn("More than one implementation " + "of @" + getSimpleName()
+ " (now relying on @Conditionals to pick one): " + factories);
}
return factories.toArray(new String[factories.size()]);
}
factories檔案舉例
org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker=\
org.springframework.cloud.netflix.hystrix.HystrixCircuitBreakerConfiguration
4、例項化被載入配置的類
HystrixCircuitBreakerConfiguration這個bean就是一個配置bean,所以通過以上流程spring最終實現了自動找到配置bean的目的。
我理解是個spi外掛化的過程,spring標準化了元件接入的流程。
@Configuration
public class HystrixCircuitBreakerConfiguration {
@Bean
public HystrixCommandAspect hystrixCommandAspect() {
return new HystrixCommandAspect();
}
@Bean
public HystrixShutdownHook hystrixShutdownHook() {
return new HystrixShutdownHook();
}
@Bean
public HasFeatures hystrixFeature() {
return HasFeatures.namedFeatures(new NamedFeature("Hystrix", HystrixCommandAspect.class));
}
@Configuration
@ConditionalOnProperty(value = "hystrix.stream.endpoint.enabled", matchIfMissing = true)
@ConditionalOnWebApplication
@ConditionalOnClass({ Endpoint.class, HystrixMetricsStreamServlet.class })
protected static class HystrixWebConfiguration {
@Bean
public HystrixStreamEndpoint hystrixStreamEndpoint() {
return new HystrixStreamEndpoint();
}
@Bean
public HasFeatures hystrixStreamFeature() {
return HasFeatures.namedFeature("Hystrix Stream Servlet", HystrixStreamEndpoint.class);
}
}
自定義starter
1、寫bean配置類
@Configuration
@ConditionalOnClass(ExampleService.class)
//屬性配置類
@EnableConfigurationProperties(ExampleServiceProperties.class)
public class ExampleAutoConfigure {
@Autowired
private ExampleServiceProperties properties;
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = "example.service",value = "enabled",havingValue = "true")
ExampleService exampleService (){
return new ExampleService(properties.getPrefix(),properties.getSuffix());
}
}
2、寫屬性配置類
如果有需要配置的屬性,可以加一個屬性配置類,properties的屬性會自動注入到配置類中。
@ConfigurationProperties("example.service")
public class ExampleServiceProperties {
private String prefix;
private String suffix;
//省略 getter setter
3、pom檔案
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>example-spring-boot-starter</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
</dependencies>
4、新增spring .factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.example.autocinfigure.ExampleAutoConfigure
5、打包
mvn package
springboot啟動原理
@springbootapplication註解
@springbootapplication包含了很多註解,如下圖所示。核心在於自動配置註解@EnableAutoConfiguration,原理如上文所述
springbootappliction.run()
run方法就是初始化ioc容器和建立各種bean的過程,核心在refresh()
相關文章
- SpringBoot | 自動配置原理Spring Boot
- SpringBoot自動配置原理Spring Boot
- springboot 自動配置原理Spring Boot
- SpringBoot啟動流程分析原理(一)Spring Boot
- springboot_自動配置原理Spring Boot
- SpringBoot的自動配置原理Spring Boot
- SpringBoot自動配置原理解析Spring Boot
- springboot 配置熱啟動 不需重啟自動部署Spring Boot
- springboot啟動流程Spring Boot
- SpringBoot-04-自動配置原理再理解Spring Boot
- SpringBoot 啟動原理Spring Boot
- SpringBoot啟動原理Spring Boot
- SpringBoot啟動流程解析Spring Boot
- 圖解原始碼 | SpringBoot中自動配置原理圖解原始碼Spring Boot
- SpringBoot自動配置原理原始碼級別分析Spring Boot原始碼
- SpringBoot2.4.0中嵌入式servlet容器的自動配置以及啟動原理(自我理解)Spring BootServlet
- springBoot-啟動原理Spring Boot
- SpringBoot啟動流程總結Spring Boot
- 笑死,面試官又問我SpringBoot自動配置原理面試Spring Boot
- Springboot MVC 自動配置Spring BootMVC
- SpringBoot的自動配置Spring Boot
- SpringBoot(03)——自動配置Spring Boot
- SpringBoot(二)自動配置Spring Boot
- SpringBoot 啟動類的原理Spring Boot
- Ubuntu自動啟動配置指令碼Ubuntu指令碼
- SpringBoot 自動配置原理,翻原始碼看一下Spring Boot原始碼
- SpringBoot啟動程式碼和自動裝配原始碼分析Spring Boot原始碼
- centos 自動啟動指令碼和自啟動服務CentOS指令碼
- 這一次搞懂SpringBoot核心原理(自動配置、事件驅動、Condition)Spring Boot事件
- springboot 自動配置案例分析Spring Boot
- SpringBoot自動裝配原理分析Spring Boot
- SpringBoot系列--自動裝配原理Spring Boot
- Spring Boot 自動配置原理Spring Boot
- [springboot]一啟動就自動停止了Spring Boot
- springboot之啟動原理解析Spring Boot
- SpringBoot | 2.1 SpringBoot自動裝配原理Spring Boot
- SpringBoot原始碼解析-啟動流程(二)Spring Boot原始碼
- SpringBoot原始碼解析-啟動流程(一)Spring Boot原始碼