spring boot 依靠 spring 的核心功能,减少了项目开发中繁杂的依赖管理和配置文件管理;
将整合其他框架所需的样板代码及配置文件提前准备好,想要使用哪个框架,直接在依赖中引入该框架的 starter 就行了;
(1)依赖管理:spring boot 将市面上常用的开源框架和中间件的依赖都整合成了 starter 依赖,想要整合哪个开源框架,直接在 pom 文件中引入该框架的 starter 依赖即可;
(2)配置文件管理:spring boot 使用 .properties、.yml 配置文件为所有引入的框架或中间件提供配置项的管理;
@Configuration 注解,就是标注该启动类是 spring ioc 容器中的一个配置类;
@EnableAutoConfiguration:该注解的作用是使用 @Import 注解引入了两个类,AutoConfigurationImportSelector 和 AutoConfigurationPackages.Registrar;
该注解的作用是,打开自动配置的功能,也可以关闭某个自动配置的选项,如关闭数据源自动配置功能: @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class });
@ComponentScan:包扫描注解;
AutoConfigurationPackages.Registrar 的作用:告诉 spring boot,基包是哪一个;
该类的源码:
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 接口的作用:用于存储导入配置中的【基包】;
// new PackageImports(metadata).getPackageNames():就是启动类所在的包路径名,也就是所谓的【基包】;
// 那么 registerBeanDefinitions 这个方法的作用就是,找到所要扫描的【基包】,将该包下相应的类加入到 ioc 容器中;
// 这也是为什么启动类要在其他类的最上层的原因;
AutoConfigurationImportSelector 的作用:加载 spring boot 自己写的配置类;
该类实现的接口:AutoConfigurationImportSelector -> DeferredImportSelector -> ImportSelector
首先说明 ImportSelector 接口的作用;
可以简单理解为,这个接口和 @Import + @Configuration 两个注解搭配使用的;
ImportSelector 接口有一个方法 String[] selectImports(AnnotationMetadata importingClassMetadata);
这个方法的作用是,如果你定义了一个接口 InterfaceA,又写了两个实现类 ClassB、ClassC;
如果 ClassB、ClassC 上没加 @Component 等 spring 注解,你又想要把这个类加入到 spring ioc 容器中;
可以使用这个接口方法实现;(具体的代码示例就不写了...)
回到 spring boot 中来,让我们看看 AutoConfigurationImportSelector 类使用 selectImports 方法将哪些类加入到了 ioc 容器中;
源码中最主要的一句代码:
Enumeration urls = classLoader.getResources("META-INF/spring.factories");
// 去 classLoader 类路径下找 "META-INF/spring.factories" 文件;
// 这个就是 spring 的 SPI 机制;
// 也是使用这个 SPI 机制,实现了自动装配机制,实现了各种 starter 依赖;
这个就是在加载 spring.factories 文件中带有 @EnableAutoConfiguration 注解所有配置的值,也就是下面的东西:
# 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,\ org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\ org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\ org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\ org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\ org.springframework.boot.autoconfigure.context.LifecycleAutoConfiguration,\ org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\ org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\ org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\ org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,\ org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,\ org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveDataAutoConfiguration,\ org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,\ org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveDataAutoConfiguration,\ org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,\ org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRestClientAutoConfiguration,\ org.springframework.boot.autoconfigure.data.jdbc.JdbcRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,\ org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration,\ org.springframework.boot.autoconfigure.data.mongo.MongoReactiveRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration,\ org.springframework.boot.autoconfigure.data.neo4j.Neo4jReactiveDataAutoConfiguration,\ org.springframework.boot.autoconfigure.data.neo4j.Neo4jReactiveRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.r2dbc.R2dbcDataAutoConfiguration,\ org.springframework.boot.autoconfigure.data.r2dbc.R2dbcRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,\ org.springframework.boot.autoconfigure.data.redis.RedisReactiveAutoConfiguration,\ org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration,\ org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration,\ org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientAutoConfiguration,\ org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\ org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,\ org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration,\ org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration,\ org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration,\ org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration,\ org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration,\ org.springframework.boot.autoconfigure.hazelcast.HazelcastJpaDependencyAutoConfiguration,\ org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration,\ org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration,\ org.springframework.boot.autoconfigure.influx.InfluxDbAutoConfiguration,\ org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration,\ org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration,\ org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration,\ org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\ org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration,\ org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration,\ org.springframework.boot.autoconfigure.jdbc.XADataSourceAutoConfiguration,\ org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\ org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration,\ org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration,\ org.springframework.boot.autoconfigure.jms.JndiConnectionFactoryAutoConfiguration,\ org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration,\ org.springframework.boot.autoconfigure.jms.artemis.ArtemisAutoConfiguration,\ org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration,\ org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration,\ org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration,\ org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration,\ org.springframework.boot.autoconfigure.availability.ApplicationAvailabilityAutoConfiguration,\ org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration,\ org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration,\ org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration,\ org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration,\ org.springframework.boot.autoconfigure.mail.MailSenderValidatorAutoConfiguration,\ org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration,\ org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\ org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration,\ org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration,\ org.springframework.boot.autoconfigure.neo4j.Neo4jAutoConfiguration,\ org.springframework.boot.autoconfigure.netty.NettyAutoConfiguration,\ org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\ org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration,\ org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration,\ org.springframework.boot.autoconfigure.r2dbc.R2dbcTransactionManagerAutoConfiguration,\ org.springframework.boot.autoconfigure.rsocket.RSocketMessagingAutoConfiguration,\ org.springframework.boot.autoconfigure.rsocket.RSocketRequesterAutoConfiguration,\ org.springframework.boot.autoconfigure.rsocket.RSocketServerAutoConfiguration,\ org.springframework.boot.autoconfigure.rsocket.RSocketStrategiesAutoConfiguration,\ org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration,\ org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration,\ org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration,\ org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration,\ org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration,\ org.springframework.boot.autoconfigure.security.rsocket.RSocketSecurityAutoConfiguration,\ org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyAutoConfiguration,\ org.springframework.boot.autoconfigure.sendgrid.SendGridAutoConfiguration,\ org.springframework.boot.autoconfigure.session.SessionAutoConfiguration,\ org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfiguration,\ org.springframework.boot.autoconfigure.security.oauth2.client.reactive.ReactiveOAuth2ClientAutoConfiguration,\ org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration,\ org.springframework.boot.autoconfigure.security.oauth2.resource.reactive.ReactiveOAuth2ResourceServerAutoConfiguration,\ org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration,\ org.springframework.boot.autoconfigure.sql.init.SqlInitializationAutoConfiguration,\ org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration,\ org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration,\ org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration,\ org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration,\ org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration,\ org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration,\ org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration,\ org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration,\ org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration,\ org.springframework.boot.autoconfigure.web.reactive.ReactiveMultipartAutoConfiguration,\ org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration,\ org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration,\ org.springframework.boot.autoconfigure.web.reactive.WebSessionIdResolverAutoConfiguration,\ org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration,\ org.springframework.boot.autoconfigure.web.reactive.function.client.ClientHttpConnectorAutoConfiguration,\ org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration,\ org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration,\ org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration,\ org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration,\ org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration,\ org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration,\ org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\ org.springframework.boot.autoconfigure.websocket.reactive.WebSocketReactiveAutoConfiguration,\ org.springframework.boot.autoconfigure.websocket.servlet.WebSocketServletAutoConfiguration,\ org.springframework.boot.autoconfigure.websocket.servlet.WebSocketMessagingAutoConfiguration,\ org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration,\ org.springframework.boot.autoconfigure.webservices.client.WebServiceTemplateAutoConfiguration
这么多都是些啥?
这些就是 spring boot 全场景下的配置类;
为什么 spring boot 只需要引入 spring-boot-starter-web 就可以使用 spring mvc + tomcat 的功能了,完全不需要写任何配置文件,或是创建 DispatcherServlet 对象;
为什么我们只需要在 yml 配置文件中添加数据库连接信息,就可以直接连接数据库了,也没有写过 Class.forName("com.mysql.jdbc.Driver") 相关的代码;
就是因为 spring boot 已经将市面上大部分的开源框架或中间件的全场景配置都配置好了,并将配置类的路径名写到了 spring.factories 这个文件中;
当 spring boot 启动的时候就会加载这个文件,并将程序员想要添加的配置类加载到了 ioc 容器中;
@EnableAutoConfiguration 给容器导入 META-INF/spring.factories 里定义的自动配置类,筛选有效的自动配置类;
每一个自动配置类结合对应的 xxxProperties.java 读取配置文件进行自动配置功能;
Spring Boot 启动流程
既然是 Spring Boot 的启动流程,那么入口必然是启动类中的 run 方法:
@SpringBootApplication public class StudyBootApplication { public static void main(String[] args) { SpringApplication.run(StudyBootApplication.class, args); } }
//(1)创建 SpringApplication 执行该类的 run 方法;
new SpringApplication(primarySources).run(args);
//(2)执行 spring 容器刷新方法,就是启动 spring ioc 容器;
refreshContext(context);
//(3)执行 BeanFacotryPostProcessor 接口实现类;
invokeBeanFactoryPostProcessors(beanFactory);
//(4)扫描配置类,该方法会加载启动类上 @Import 注解引入的类,并从注册表中的配置类进一步派生bean定义
configurationClassPostProcessor .postProcessBeanDefinitionRegistry(registry);
//(5)onRefresh()方法中,启动 tomcat;
createWebServer() = factory.getWerServer(getSelfInitializer);
//(6)tomcat 启动加载所有 DispatcherServlet;
//(7)DispatcherServlet 加载九大组件;
1、启动 spring boot 启动类中的 main 方法;
2、使用启动类的 class 对象,创建一个 SpringApplication 对象;
在这个类的构造函数中,会执行 getSpringFactoriesInstances 这个方法,从 META-INF/spring.factories 文件中加载 ContextInitializer 初始化器和 Listener 监听器;
将加载到的类信息放入缓存中,等着 ioc 容器启动的时候加载使用;
3、然后执行 SpringApplication 对象的 run 方法;
该方法中会执行两个很重要的方法,prepareContext 和 refreshContext 方法;
prepareContext 将启动类的 beanDefinition 注册到 register 当中,方便后续解析;
refreshContext 就是调用执行 spring ioc 容器的刷新方法;
4、开始执行 ioc 容器的 refresh 方法;
其中会执行 invokeBeanFactoryPostProcessor 方法,这里面会执行一个 ConfigurationClassPostProcessor 配置类解析的后置处理器;
ConfigurationClassPostProcessor 实现了两个接口,BeanFactoryPostProcessor 和 BeanDefinitionRegistryPostProcessor;
ConfigurationClassPostProcessor 会解析启动类上的注解,并执行由 @Import 注解注入的 AutoConfigurationImportSelector 类的 process 方法;
5、process 的方法中,会加载 spring.factories 文件中标注了 @EnableAutoConfiguration 注解的自动装配配置类;
这些配置类中会用 @Condition 条件注解,在 ioc 容器或引入的 jar 包中或配置文件中比对条件,来决定是否加载对应的 bean;
6、process 方法执行完毕后,剩下的就是 spring ioc 容器的启动流程;
7、在 onrefresh() 方法中会执行 createWebServer() 方法,创建 Web 容器,也就是启动 tomcat;
8、tomcat 启动后执行 Servlet 的生命周期,也就是执行 DispatcherServlet 的 initStrategies 初始化方法;
在 initStrategies 方法中会从 spring ioc 容器中初始化 spring mvc 运行所需的九大组件;
handlerMapping 控制器;handlerAdapter 适配器;handlerExceptionResolver 异常解析器;viewResolver 视图解析器;
9、执行后续的 spring ioc 容器的启动流程