栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

SpringBoot自动配置原理源码解析

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SpringBoot自动配置原理源码解析

自动配置原理 DeferredimportSelector Spring集成外部框架

Spring集成其他框架,一般都是通过注解@EnableXXX的方式,在@EnableXXX注解中会有@import注解,@import导入的Bean(有3种方式:@import({ 类名.class , 类名.class… });importSelector;importBeanDefinitionRegistrar)其实就是集成框架的关键Bean。

自定义配置类

如果项目中已经有默认的组件A配置(通过@import),此时我们自己要自定义一个组件A配置(通过@Bean,@Component,@import等方式)来达到一个扩展性,那么就需要控制默认配置和自定义配置之间的顺序,来保证自定义的配置会覆盖默认的配置。importSelector的方式无法控制顺序,所以需要用DeferredimportSelector来保证默认配置延迟导入解析。这样就会先解析通过@Bean,@Component,@import等方式导入的自定义配置,在最后解析默认配置时如果发现我们已经配置了相同的组件,那么就不再使用默认的配置(@ConditionalOnBean)。

DeferredimportSelector原理

DeferredimportSelector除了有延迟的特性,还有分组的特性。

DeferredimportSelector通过getimportGroup看是否返回一个自定义分组Group:如果有,就会调用自定义分组中的process方法进而调用自定义分组的selectimports方法;如果没有,就会调用importSelector的selectimports方法,该方法的排序只会影响该分组中的顺序,不会影响整个容器的顺序。

SpringBoot把Bean都管理在spring.factories中,然后进行读取,读取出来所有jar包中的spring.factories之后,把里面String类型的全类名放到list中交给spring注册成BeanDefinition。

源代码 @EnableAutoConfiguration

SpringBoot启动类,其中@SpringBootApplication注解表示是SpringBoot应用

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

@SpringBootApplication注解,其中@EnableAutoConfiguration表示启用自动配置

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
      @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {

@EnableAutoConfiguration注解,其中就有@import(AutoConfigurationimportSelector.class),就是通过importSelector的方式导入一个class

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@documented
@Inherited
@AutoConfigurationPackage
@import(AutoConfigurationimportSelector.class)
public @interface EnableAutoConfiguration {
AutoConfigurationimportSelector

AutoConfigurationimportSelector实现了DeferredimportSelector,重写getimportGroup返回自定义分组AutoConfigurationGroup。从AutoConfigurationGroup#process入手:

public class AutoConfigurationimportSelector implements DeferredimportSelector, 		BeanClassLoaderAware,ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {
	...
  //该方法会返回所有的自动配置类  
	protected AutoConfigurationEntry getAutoConfigurationEntry(Annotationmetadata annotationmetadata) {
		if (!isEnabled(annotationmetadata)) {
			return EMPTY_ENTRY;
		}
    //获取@EnableAutoConfiguration的所有属性:exclude、excludeName
		AnnotationAttributes attributes = getAttributes(annotationmetadata);
    //从所有jar包的meta-INF/spring.factories中获得候选的自动配置类
		List configurations = getCandidateConfigurations(annotationmetadata, attributes);
    //去重
		configurations = removeDuplicates(configurations);
    //获取需要排除的类
		Set exclusions = getExclusions(annotationmetadata, attributes);
		checkExcludedClasses(configurations, exclusions);
		configurations.removeAll(exclusions);
    // 通过读取spring.factories中的AutoConfigurationimportFilter(包括OnBeanConditionOnClassConditionOnWebApplicationCondition等)进行过滤
		configurations = getConfigurationClassFilter().filter(configurations);
		fireAutoConfigurationimportEvents(configurations, exclusions);
		return new AutoConfigurationEntry(configurations, exclusions);
	}
  ...
    
  @Override
	public Class getimportGroup() {
		return AutoConfigurationGroup.class;
	}  
  ...
    
	private static class AutoConfigurationGroup
			implements DeferredimportSelector.Group, BeanClassLoaderAware, BeanFactoryAware, ResourceLoaderAware {

		...
		@Override
		public void process(Annotationmetadata annotationmetadata, DeferredimportSelector deferredimportSelector) {
			...
			AutoConfigurationEntry autoConfigurationEntry = ((AutoConfigurationimportSelector) deferredimportSelector)
					.getAutoConfigurationEntry(annotationmetadata);
			this.autoConfigurationEntries.add(autoConfigurationEntry);
			for (String importClassName : autoConfigurationEntry.getConfigurations()) {
				this.entries.putIfAbsent(importClassName, annotationmetadata);
			}
		}

    //排序,只会对当前组中的类进行排序
		@Override
		public Iterable selectimports() {
			if (this.autoConfigurationEntries.isEmpty()) {
				return Collections.emptyList();
			}
			Set allExclusions = this.autoConfigurationEntries.stream()
					.map(AutoConfigurationEntry::getExclusions).flatMap(Collection::stream).collect(Collectors.toSet());
			Set processedConfigurations = this.autoConfigurationEntries.stream()
					.map(AutoConfigurationEntry::getConfigurations).flatMap(Collection::stream)
					.collect(Collectors.toCollection(linkedHashSet::new));
			processedConfigurations.removeAll(allExclusions);

			return sortAutoConfigurations(processedConfigurations, getAutoConfigurationmetadata()).stream()
					.map((importClassName) -> new Entry(this.entries.get(importClassName), importClassName))
					.collect(Collectors.toList());
		}

		...

	}
  
getCandidateConfigurations

AutoConfigurationGroup#process会调用getAutoConfigurationEntry,其中getCandidateConfigurations会从所有jar包的meta-INF/spring.factories(K-V形式)中获得候选的自动配置类,但并不是文件中的所有key都需要,只需要key为EnableAutoConfiguration(getSpringFactoriesLoaderFactoryClass)的类;

  protected List getCandidateConfigurations(Annotationmetadata metadata, AnnotationAttributes attributes) {
     List configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
           getBeanClassLoader());
     ...
  }
	//表示只需要EnableAutoConfiguration的key的类
	protected Class getSpringFactoriesLoaderFactoryClass() {
		return EnableAutoConfiguration.class;
	}

springboot官方配置的spring-boot-autoconfigure-2.3.6.RELEASE.jar!/meta-INF/spring.factories示例:

其中包含key为EnableAutoConfiguration的类有100多个(不同版本数量会有差异),这些配置类就提供了不同的第三方框架所需要的Bean,这些配置类当中也不是所有都需要,还会根据我们导入的starter进行匹配生效。

# 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,
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.Neo4jRepositoriesAutoConfiguration,
org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration,
org.springframework.boot.autoconfigure.data.r2dbc.R2dbcDataAutoConfiguration,
org.springframework.boot.autoconfigure.data.r2dbc.R2dbcRepositoriesAutoConfiguration,
org.springframework.boot.autoconfigure.data.r2dbc.R2dbcTransactionManagerAutoConfiguration,
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.orm.jpa.HibernateJpaAutoConfiguration,
org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration,
org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration,
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.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.ReactiveWebServerFactoryAutoConfiguration,
org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration,
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

# 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
getConfigurationClassFilter().filter

读取spring.factories中的AutoConfigurationimportFilter,根据OnBeanCondition,OnClassCondition,OnWebApplicationCondition等条件对读取到的配置类进行过滤,决定哪些配置可以生效。

比如配置类A(onClassCondition=B),只在当前类路径中有B这个类的时候会生效,否则不生效。

	private ConfigurationClassFilter getConfigurationClassFilter() {
		if (this.configurationClassFilter == null) {
			List filters = getAutoConfigurationimportFilters();
			...
	}
	...
	protected List getAutoConfigurationimportFilters() {
    //读取spring.factories中的AutoConfigurationimportFilter
		return SpringFactoriesLoader.loadFactories(AutoConfigurationimportFilter.class, this.beanClassLoader);
	}

过滤就是根据当前配置的启动器starter决定哪些生效,比如当前只配置3个starter,留下来的配置类只剩下26个。


    
        org.springframework.boot
        spring-boot-starter-web
    


    
        org.springframework.boot
        spring-boot-starter
    

    
        org.springframework.boot
        spring-boot-starter-test
        test
    


@Conditional派生注解
@Conditional扩展注解指定条件
@ConditionalOnJava系统的java版本是否符合要求
@ConditionalOnBean容器中存在指定Bean;
@ConditionalOnMissingBean容器中不存在指定Bean;
@ConditionalOnexpression满足SpEL表达式指定
@ConditionalOnClass系统中有指定的类
@ConditionalOnMissingClass系统中没有指定的类
@ConditionalOnSingleCandidate容器中只有一个指定的Bean,或者这个Bean是首选Bean
@ConditionalOnProperty系统中指定的属性是否有指定的值
@ConditionalOnResource类路径下是否存在指定资源文件
@ConditionalOnWebApplication当前是web环境
@ConditionalOnNotWebApplication当前不是web环境
@ConditionalOnJndiJNDI存在指定项
流程总结

springboot利用@import注解导入DeferredimportSelector(延迟加载、分组排序),基于importSelector的类可以批量导入class,所以可以读取所有jar包中的spring.factories,从spring.factories中获得候选的自动配置类,然后进行过滤,最后将读取的配置类返回一个list,返回之后spring就会将list中的类注册成BeanDefinition。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/591566.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号