简要概述
我们知道SpringBoot是简化了我们的配置,那它是怎么做到的呢?
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class))
public @interface SpringBootApplication {
...
}
注意到了这里使用@SpringBootApplication注解
继续找到@EnableAutoConfiguration源码:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(EnableAutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class>[] exclude() default {};
String[] excludeName() default {};
}
@Import(EnableAutoConfigurationImportSelector.class)导入一个组件
@AutoConfigurationPackage:存储自动配置类的包通过
/**
*返回自动配置类的名字
*/
protected List getCandidateConfigurations(AnnotationMetadata metadata,
AnnotationAttributes attributes) {
List configurations = SpringFactoriesLoader.loadFactoryNames(
getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());
Assert.notEmpty(configurations,
"No auto configuration classes found in META-INF/spring.factories. If you "
+ "are using a custom packaging, make sure that file is correct.");
return configurations;
}
自动配置类位于 META-INF/spring.factories文件中
在我们连接spring是怎么识别出import注解并且把组件注册进去的时候先来了解下BeanFactoryPostProcessor的实现类BeanDefinitionRegistryPostProcessor
而BeanDefinitionRegistryPostProcessor的实现类就是ConfigurationClassPostProcessor;
负责解析处理所有@Configuration标签类,并将Bean定义注册到BeanFactory中。
ConfigurationClassPostProcessor通过ConfigurationClassParser进行实际解析操作。
ConfigurationClassParser将会进行如下解析处理:
处理嵌套的MemberClass
处理@PropertySource标签,用来解析属性文件并设置到Environment中。
处理@ComponentScan标签,扫描package下的所有Class并进行迭代解析。
处理@Import标签。
处理@ImportResource标签。
处理@Bean标签。
处理所有继承的Interface上的@Bean标签。
处理SuperClass。
处理标签中的DeferredImport。
等
代码调用链如下
org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors
->org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors()
->org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors
->org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions
->org.springframework.context.annotation.ConfigurationClassParser.parse()
->org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass
@Conditional注解
只有满足条件才加载
几个子类如下
SpringFactoriesLoader
它扩展了java原生的SPI机制,会从META-INF/spring.factories中查找类,然后根据条件注解,再使用EnableAutoConfigurationImportSelector导入满足条件的类到容器中
小结
SpringBoot的核心总结如下
1.@Conditional注解,只有满足条件才加载
2.@Import注解用于根据条件导入配置类
3.SpringFactoriesLoader,从文件中加载默认的配置类
Spring Boot启动流程
Spring Boot应用的整个启动流程都封装在SpringApplication.run方法中,其整个流程真的是太长太长了,但本质上就是在Spring容器启动的基础上做了大量的扩展,按照这个思路来看看源码:
publicConfigurableApplicationContextrun(String...args){
StopWatch stopWatch=newStopWatch();
stopWatch.start();
ConfigurableApplicationContext context=null;
FailureAnalyzers analyzers=null;
configureHeadlessProperty();//
①SpringApplicationRunListenerslisteners=getRunListeners(args);
listeners.starting();
try{
②ApplicationArguments applicationArguments=newDefaultApplicationArguments(args);
ConfigurableEnvironment environment=prepareEnvironment(listeners,applicationArguments);//
③Banner printedBanner=printBanner(environment);//
④context=createApplicationContext();//
⑤analyzers=newFailureAnalyzers(context);//
⑥prepareContext(context,environment,listeners,applicationArguments,printedBanner);//
⑦ refreshContext(context);//
⑧afterRefresh(context,applicationArguments);//
⑨listeners.finished(context,null);
stopWatch.stop();
returncontext;
}catch(Throwableex){
handleRunFailure(context,listeners,analyzers,ex);
thrownewIllegalStateException(ex);
}
}
① 通过SpringFactoriesLoader查找并加载所有的 SpringApplicationRunListeners,通过调用starting()方法通知所有的SpringApplicationRunListeners:应用开始启动了。SpringApplicationRunListeners其本质上就是一个事件发布者,它在SpringBoot应用启动的不同时间点发布不同应用事件类型(ApplicationEvent),如果有哪些事件监听者(ApplicationListener)对这些事件感兴趣,则可以接收并且处理。还记得初始化流程中,SpringApplication加载了一系列ApplicationListener吗?这个启动流程中没有发现有发布事件的代码,其实都已经在SpringApplicationRunListeners这儿实现了。
org.springframework.boot.SpringApplication.run()
->org.springframework.boot.SpringApplication.initialize(Object[])
->org.springframework.core.io.support.SpringFactoriesLoader.loadFactoryNames(Class>, ClassLoader)
从META-INF/spring.factories中依次加载ApplicationContextInitializer ApplicationListener
->org.springframework.boot.SpringApplication.run(Object, String...)
->org.springframework.boot.SpringApplication.refreshContext()
->org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh()
->org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors() 执行BeanFactory的前后拦截器 ConfigurationClassPostProcessor 用于执行自动化配置的
->org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors()
->org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors()
->org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions()
->org.springframework.context.annotation.ConfigurationClassParser.processDeferredImportSelectors() 我们的自定义组件是通过@Import注解在这里导入的
->org.springframework.boot.autoconfigure.AutoConfigurationImportSelector.selectImports()
->org.springframework.boot.autoconfigure.AutoConfigurationImportSelector.getCandidateConfigurations() 这个就是众多的自动化配置类
->org.springframework.core.io.support.SpringFactoriesLoader.loadFactoryNames(Class>, ClassLoader) 最终调用到这里,即Java的SPI机制 会去加载META-INF/spring.factories下的实现类
SpringBoot为我们导入的自动配置的类
[org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,
org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration,
org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration,
org.springframework.boot.autoconfigure.websocket.WebSocketAutoConfiguration,
org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration,
org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration,
org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration,
org.springframework.boot.autoconfigure.security.oauth2.OAuth2AutoConfiguration,
org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration,
org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration,
org.springframework.boot.autoconfigure.cloud.CloudAutoConfiguration,
org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration,
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,
org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration,
org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration,
org.springframework.boot.autoconfigure.jdbc.XADataSourceAutoConfiguration,
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,
org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,
org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration,
org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,
org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,
org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,
org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration,
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration,
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,
org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,
org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration,
org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration,
org.springframework.boot.autoconfigure.data.ldap.LdapDataAutoConfiguration,
org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,
org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration,
org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,
org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,
org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration,
org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,
org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration,
org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration,
org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration,
org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration,
org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration,
org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfiguration,
org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration,
org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration,
org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration,
org.springframework.boot.autoconfigure.elasticsearch.jest.JestAutoConfiguration,
org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,
org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,
org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration,
org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration,
org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration,
org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration,
org.springframework.boot.autoconfigure.hazelcast.HazelcastJpaDependencyAutoConfiguration,
org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration,
org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration,
org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration,
org.springframework.boot.autoconfigure.jms.JndiConnectionFactoryAutoConfiguration,
org.springframework.boot.autoconfigure.jms.artemis.ArtemisAutoConfiguration,
org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration,
org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration,
org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration,
org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration,
org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration,
org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration,
org.springframework.boot.autoconfigure.mail.MailSenderValidatorAutoConfiguration,
org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration,
org.springframework.boot.autoconfigure.social.TwitterAutoConfiguration,
org.springframework.boot.autoconfigure.social.LinkedInAutoConfiguration,
org.springframework.boot.autoconfigure.social.FacebookAutoConfiguration,
org.springframework.boot.autoconfigure.social.SocialWebAutoConfiguration,
org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration,
org.springframework.boot.autoconfigure.mobile.DeviceDelegatingViewResolverAutoConfiguration,
org.springframework.boot.autoconfigure.mobile.DeviceResolverAutoConfiguration,
org.springframework.boot.autoconfigure.mobile.SitePreferenceAutoConfiguration,
org.springframework.boot.autoconfigure.reactor.ReactorAutoConfiguration,
org.springframework.boot.autoconfigure.security.FallbackWebSecurityAutoConfiguration,
org.springframework.boot.autoconfigure.security.SecurityFilterAutoConfiguration,
org.springframework.boot.autoconfigure.sendgrid.SendGridAutoConfiguration,
org.springframework.boot.autoconfigure.session.SessionAutoConfiguration,
org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration,
org.springframework.boot.autoconfigure.web.HttpEncodingAutoConfiguration,
org.springframework.boot.autoconfigure.web.MultipartAutoConfiguration,
org.springframework.boot.autoconfigure.web.ServerPropertiesAutoConfiguration,
org.springframework.boot.autoconfigure.web.WebClientAutoConfiguration,
org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration,
org.springframework.boot.autoconfigure.websocket.WebSocketMessagingAutoConfiguration]
还比较多,后面慢慢补