SpringBoot内置的自动配置使开发变得很方便,所以这次就来看看它的启动源码和它的自动化配置的实现原理。
启动类:
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
可以看到这个启动类中有两部分:@SpringBootApplication和SpringApplication.run(DemoApplication.class, args)两部分。每个Spring Boot项目都包含这两部分。
@SpringBootApplication
-
@Target(ElementType.TYPE) // 注解的适用范围,TYPE用于描述类、接口、enum声明 -
@Retention(RetentionPolicy.RUNTIME) // 注解的生命周期 -
@Documented // 表明这个注解应该被javadoc记录 -
@Inherited // 子类可以继承该注解 -
@SpringBootConfiguration // 继承了Configuration,表示当前是注解类 -
@EnableAutoConfiguration // 开启SpringBoot的注解功能,借助@import的帮助 -
@ComponentScan(excludeFilters = { // 包扫描路径设置 -
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class), -
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) }) -
public @interface SpringBootApplication { -
…… -
}
这块最重要的三个注解是:
- @Configuration:IoC容器的配置类(@SpringBootConfiguration内部有@Configuration)
- @EnableAutoConfiguration:借助@Import的支持,将所有符合自动配置条件的bean定义加载到IoC容器。
- @ComponentScan:自动扫描并加载符合条件的组件或者bean,最终将这些bean加载到IoC容器中
这里主要研究下@EnableAutoConfiguration注解:
-
@Target(ElementType.TYPE) -
@Retention(RetentionPolicy.RUNTIME) -
@Documented -
@Inherited -
@AutoConfigurationPackage -
@Import(AutoConfigurationImportSelector.class) -
public @interface EnableAutoConfiguration { -
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration"; -
…… -
}
这个注解主要有两个注解组成:
- @AutoConfigurationPackage:返回了当前主程序类的同级以及子级的包组件。
- @Import(AutoConfigurationImportSelector.class):导入自动配置的组件
先来看看@AutoConfigurationPackage的实现:
-
@Target(ElementType.TYPE) -
@Retention(RetentionPolicy.RUNTIME) -
@Documented -
@Inherited -
@Import(AutoConfigurationPackages.Registrar.class) -
public @interface AutoConfigurationPackage { -
} -
static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports { -
@Override -
public void registerBeanDefinitions(AnnotationMetadata metadata, -
BeanDefinitionRegistry registry) { -
register(registry, new PackageImport(metadata).getPackageName()); -
} -
@Override -
public Set<Object> determineImports(AnnotationMetadata metadata) { -
return Collections.singleton(new PackageImport(metadata)); -
} -
}
它其实是注册了一个Bean的定义。new PackageImport(metadata).getPackageName(),它会返回当前主程序类的同级以及子级的包组件。
这就是为什么要把主程序放在项目的顶层节点的原因。
下面再来看看@Import(AutoConfigurationImportSelector.class)的作用:
-
public String[] selectImports(AnnotationMetadata annotationMetadata) { -
if (!isEnabled(annotationMetadata)) { -
return NO_IMPORTS; -
} -
AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader -
.loadMetadata(this.beanClassLoader); -
AnnotationAttributes attributes = getAttributes(annotationMetadata); -
List<String> configurations = getCandidateConfigurations(annotationMetadata, -
attributes); -
configurations = removeDuplicates(configurations); -
Set<String> exclusions = getExclusions(annotationMetadata, attributes); -
checkExcludedClasses(configurations, exclusions); -
configurations.removeAll(exclusions); -
configurations = filter(configurations, autoConfigurationMetadata); -
fireAutoConfigurationImportEvents(configurations, exclusions); -
return StringUtils.toStringArray(configurations); -
} -
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, -
AnnotationAttributes attributes) { -
List<String> 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; -
} -
public static List<String> loadFactoryNames(Class<?> factoryClass, @Nullable ClassLoader classLoader) { -
String factoryClassName = factoryClass.getName(); -
return loadSpringFactories(classLoader).getOrDefault(factoryClassName, Collections.emptyList()); -
} -
private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) { -
MultiValueMap<String, String> result = cache.get(classLoader); -
if (result != null) { -
return result; -
} -
try { -
Enumeration<URL> urls = (classLoader != null ? -
classLoader.getResources(FACTORIES_RESOURCE_LOCATION) : -
ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION)); -
result = new LinkedMultiValueMap<>(); -
while (urls.hasMoreElements()) { -
URL url = urls.nextElement(); -
UrlResource resource = new UrlResource(url); -
Properties properties = PropertiesLoaderUtils.loadProperties(resource); -
for (Map.Entry<?, ?> entry : properties.entrySet()) { -
List<String> factoryClassNames = Arrays.asList( -
StringUtils.commaDelimitedListToStringArray((String) entry.getValue())); -
result.addAll((String) entry.getKey(), factoryClassNames); -
} -
} -
cache.put(classLoader, result); -
return result; -
} -
catch (IOException ex) { -
throw new IllegalArgumentException("Unable to load factories from location [" + -
FACTORIES_RESOURCE_LOCATION + "]", ex); -
} -
}


可以看到它会从spring-boot-autoconfigure/2.0.2.RELEASE/spring-boot-autoconfigure-2.0.2.RELEASE.jar!/META-INF/spring.factories中去获取自动配置类,然后根据反射将其实例化为JavaConfig形式的IoC容器配置类,然后将其加载到IoC容器中。

-
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.cloud.CloudAutoConfiguration,\ -
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\ -
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.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.data.ldap.LdapDataAutoConfiguration,\ -
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.Neo4jRepositoriesAutoConfiguration,\ -
org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration,\ -
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.jest.JestAutoConfiguration,\ -
org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\ -
org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,\ -
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.groovy.template.GroovyTemplateAutoConfiguration,\ -
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.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.orm.jpa.HibernateJpaAutoConfiguration,\ -
org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration,\ -
org.springframework.boot.autoconfigure.reactor.core.ReactorCoreAutoConfiguration,\ -
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.sendgrid.SendGridAutoConfiguration,\ -
org.springframework.boot.autoconfigure.session.SessionAutoConfiguration,\ -
org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientAutoConfiguration,\ -
org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration,\ -
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.ReactiveWebServerFactoryAutoConfiguration,\ -
org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration,\ -
org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration,\ -
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
执行流程篇:https://blog.youkuaiyun.com/qq_37598011/article/details/90969634
本文介绍Spring Boot启动源码和自动化配置实现原理。启动类包含@SpringBootApplication和SpringApplication.run两部分。重点研究@EnableAutoConfiguration注解,其由@AutoConfigurationPackage和@Import组成,前者返回主程序类同级及子级包组件,后者从spring.factories获取自动配置类并加载到IoC容器。
227

被折叠的 条评论
为什么被折叠?



