上一節:SpringBoot開發筆記-(1) springboot簡介和helloworldjava
helloworld
查看依賴: 項目依賴了 spring-boot-stater-parent
:程序員
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> </dependency>
spring-boot-stater-parent
點進去, 裏面還依賴了個parent
:web
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.3.2.RELEASE</version> </parent>
spring-boot-dependencies
再點進去:redis
一大堆 properties
spring
一大堆 dependencies
json
可見:segmentfault
spring-boot-dependencies 纔是springboot 全部依賴真正管理者;
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
點進去: spring-boot-starter-web幫咱們導入了web項目所依賴的依賴項:tomcat
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <version>2.3.2.RELEASE</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-json</artifactId> <version>2.3.2.RELEASE</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <version>2.3.2.RELEASE</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.2.8.RELEASE</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.8.RELEASE</version> <scope>compile</scope> </dependency> </dependencies>
spring-boot-starter
spring-boot-starter-json
spring-boot-starter-tomcat
spring-web
spring-webmvc
starter: spring boot幫助管理依賴資源;springboot
spring提供了一系列starter: mail/web/jpa/mq...session
註解類:
//....SpringBootApplication... @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @SpringBootConfiguration // 1 @EnableAutoConfiguration // 2 @ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class), @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) }) public @interface SpringBootApplication { ..... //....SpringBootConfiguration... @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Configuration // 3 public @interface SpringBootConfiguration { ..... //....Configuration... @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Component // 4 public @interface Configuration {
主要註解類:
SpringBootConfiguration
能夠看到, 有 Configuration
因此:
SpringBootApplication -> SpringBootConfiguration -> Configuration -> Component
註解了 @SpringBootApplication 就有了 @SpringBootConfiguration;就有了 @Configuration 的功能; 即:此類是配置類!
就有了 @Component 的功能;
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Configuration // 繼承了Component public @interface SpringBootConfiguration {
上面說明: HelloApplication.java註解了@SpringBootApplication 它就是一個配置類, 能夠被 AnnotationConfigApplicationContext
加載掃描起來!
按需自動注入spring.factories組件
- 路徑: org.springframework.boot.autoconfigure.EnableAutoConfiguration
此類所屬jar包
spring-boot-autoconfigure.jar
目錄下有META-INF/spring.factories
文件, 內容以下: 能夠這麼理解: 下面全部類都是配置類, 做用都相似於寫一個@Configuration
的類, 在其中初始化相應所須要的的@Bean
;# Initializers org.springframework.context.ApplicationContextInitializer=\ org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\ org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener # Application Listeners org.springframework.context.ApplicationListener=\ org.springframework.boot.autoconfigure.BackgroundPreinitializer # Auto Configuration Import Listeners org.springframework.boot.autoconfigure.AutoConfigurationImportListener=\ org.springframework.boot.autoconfigure.condition.ConditionEvaluationReportAutoConfigurationImportListener # Auto Configuration Import Filters org.springframework.boot.autoconfigure.AutoConfigurationImportFilter=\ org.springframework.boot.autoconfigure.condition.OnBeanCondition,\ org.springframework.boot.autoconfigure.condition.OnClassCondition,\ org.springframework.boot.autoconfigure.condition.OnWebApplicationCondition # Auto Configure org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\ org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\ org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\ ............省略100多個.... # Failure analyzers org.springframework.boot.diagnostics.FailureAnalyzer=\ org.springframework.boot.autoconfigure.data.redis.RedisUrlSyntaxFailureAnalyzer,\ org.springframework.boot.autoconfigure.diagnostics.analyzer.NoSuchBeanDefinitionFailureAnalyzer,\ org.springframework.boot.autoconfigure.flyway.FlywayMigrationScriptMissingFailureAnalyzer,\ org.springframework.boot.autoconfigure.jdbc.DataSourceBeanCreationFailureAnalyzer,\ org.springframework.boot.autoconfigure.jdbc.HikariDriverConfigurationFailureAnalyzer,\ org.springframework.boot.autoconfigure.r2dbc.ConnectionFactoryBeanCreationFailureAnalyzer,\ org.springframework.boot.autoconfigure.session.NonUniqueSessionRepositoryFailureAnalyzer # Template availability providers org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider=\ org.springframework.boot.autoconfigure.freemarker.FreeMarkerTemplateAvailabilityProvider,\ org.springframework.boot.autoconfigure.mustache.MustacheTemplateAvailabilityProvider,\ org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAvailabilityProvider,\ org.springframework.boot.autoconfigure.thymeleaf.ThymeleafTemplateAvailabilityProvider,\ org.springframework.boot.autoconfigure.web.servlet.JspTemplateAvailabilityProvider
//....EnableAutoConfiguration... @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @AutoConfigurationPackage // 5 @Import(AutoConfigurationImportSelector.class) // 6 public @interface EnableAutoConfiguration {} //....AutoConfigurationPackage... @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @Import(AutoConfigurationPackages.Registrar.class) // 7 public @interface AutoConfigurationPackage {} // ...Registrar... // ...ImportBeanDefinitionRegistrar... /** * {@link ImportBeanDefinitionRegistrar} to store the base package from the importing * configuration. */ static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports { @Override public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) { register(registry, new PackageImports(metadata).getPackageNames().toArray(new String[0])); } @Override public Set<Object> determineImports(AnnotationMetadata metadata) { return Collections.singleton(new PackageImports(metadata)); } } // ImportBeanDefinitionRegistrar 能夠在spring容器bean初始化的時候注入組件到容器中
// 6 處是一個 ImportSelector
// 7 處是一個ImportBeanDefinitionRegistrar
這兩處都是往容器中註冊bean, 具體參見筆記:
spring註解驅動開發-(5) 向Spring容器中註冊組件的方法
ImportBeanDefinitionRegistrar 能夠在spring容器bean初始化的時候注入組件到容器中: 在這裏打斷點能夠看到: 會把 com.niewj.springboot 包目錄註冊進去; 這樣, 此包下全部子包中的spring註解的類就都會被掃描, 並初始化註冊到spring容器的上下文;
這樣的話, spring容器在啓動容器的時候, 就會按需加載 spring-boot-autoconfigure.jar包下的META-INF/spring.factories
中配置的加載類; 達到自動配置注入bean到容器中的效果(目的就是方便開發, 不須要可憐的程序員一個一個寫@Configuration的類, 而後本身寫@Bean的方法註冊組件) 這種機制就是 SPI
深刻理解SPI機制