深度剖析SpringBoot自动配置原理,为什么SpringBoot能为我们做那么多东西

这篇具有很好参考价值的文章主要介绍了深度剖析SpringBoot自动配置原理,为什么SpringBoot能为我们做那么多东西。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本文基于spring-boot-2.2.6.RELEASE版本的源码进行说明,不同版本的源码可能会有一些区别。

一. @SpringBootApplication

1. @EnableAutoConfiguration

要清楚SpringBoot自动配置原理,就要明白@SpringBootApplication注解的组成,此注解主要是这三个注解组成:@SpringBootConfiguration@EnableAutoConfiguration@ComponentScan

下面是源码:

@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 {

@SpringBootConfiguration@ComponentScan这两个注解已经是老生常谈了,在下图中已经标注,不做太多解释了😁。

深度剖析SpringBoot自动配置原理,为什么SpringBoot能为我们做那么多东西,SpringBoot从入门到入魂,spring boot,java,后端

关键就看今天这个需要剖析的主角查看源码@EnableAutoConfiguration

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
    String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";

    Class<?>[] exclude() default {};

    String[] excludeName() default {};
}

这里又出现两个很重要的注解下面我们逐个介绍一下@AutoConfigurationPackage@Import@Import的作用就是给容器导入一个组件,这个组件可以是一个类,会在项目启动的时候执行内部的方法,这里导入的是AutoConfigurationImportSelector这个类。

2.@AutoConfigurationPackage

我们先看自动配置包注解@AutoConfigurationPackage源码:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import({AutoConfigurationPackages.Registrar.class})
public @interface AutoConfigurationPackage {
}

这里的@Import导入了AutoConfigurationPackages.Registrar.class这个组件,进去看源码:

static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
    Registrar() {
    }

    public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
        AutoConfigurationPackages.register(registry, (new PackageImport(metadata)).getPackageName());
    }

    public Set<Object> determineImports(AnnotationMetadata metadata) {
        return Collections.singleton(new PackageImport(metadata));
    }
}

这段代码的作用是将自动配置的包注册到Bean定义的注册表中。

主要看registerBeanDefinitions这个方法的作用:

  1. AnnotationMetadata metadata: 包含了注解元数据的对象,有关正在扫描的类的注解信息。

  2. BeanDefinitionRegistry registry: 负责保存和管理应用程序中所有的Bean定义。

  3. AutoConfigurationPackages.register(registry, (new PackageImport(metadata)).getPackageName()): 这是方法的具体实现。它调用了AutoConfigurationPackagesregister方法,并将注册表和包名作为参数传递给该方法。

简单来说就是通过Registrar给容器中导入一系列的组件,并将指定包下的所有组件注册到Spring容器中。

我们可以通过断点来验证此结论:将上面的代码打上断点查看元注解信息就是你的SpringBoot启动类。

深度剖析SpringBoot自动配置原理,为什么SpringBoot能为我们做那么多东西,SpringBoot从入门到入魂,spring boot,java,后端

计算出第二个参数值会返回包名,SpringBoot会根据你的包名加载所有扫描出来的组件信息。

深度剖析SpringBoot自动配置原理,为什么SpringBoot能为我们做那么多东西,SpringBoot从入门到入魂,spring boot,java,后端

二. 初始加载自动配置类

上面还导入了AutoConfigurationImportSelector.class这个组件,点击源码追踪到selectImports这个方法:

/**
 * 根据指定的注解元数据,选择要导入的组件。
 * @param annotationMetadata 注解元数据,包含有关正在扫描的类的注解信息
 * @return 要导入的组件类名数组
 */
public String[] selectImports(AnnotationMetadata annotationMetadata) {
    // 如果当前组件不是启用状态,则返回一个空数组
    if (!this.isEnabled(annotationMetadata)) {
        return NO_IMPORTS;
    } else {
        // 从类加载器中加载自动配置元数据
        AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
        // 获取与指定注解元数据相匹配的自动配置条目
        AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(autoConfigurationMetadata, annotationMetadata);
        // 将自动配置条目中的配置类名转换成字符串数组并返回
        return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    }
}

这段代码的核心在于getAutoConfigurationEntry这个方法,目的就是给容器中批量导入一些组件。

getAutoConfigurationEntry(autoConfigurationMetadata, annotationMetadata);

深入此方法的源码:

```java
/**
 * 获取自动配置条目,决定哪些配置类将被导入到Spring容器中进行自动配置。
 *
 * @param autoConfigurationMetadata 自动配置的元数据,用于获取配置类信息。
 * @param annotationMetadata       注解元数据,用于获取注解信息。
 * @return AutoConfigurationEntry对象,包含需要导入的配置类和排除的配置类信息。
 */
protected AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata, AnnotationMetadata annotationMetadata) {
    if (!this.isEnabled(annotationMetadata)) {
        // 如果未启用自动配置,则返回一个空的AutoConfigurationEntry对象
        return EMPTY_ENTRY;
    } else {
        // ①获取注解元数据中的属性信息
        AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
        // 获取候选的配置类列表
        List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
        // 去除重复的配置类
        configurations = this.removeDuplicates(configurations);
        // 获取需要排除的配置类集合
        Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
        // 检查是否有配置类被排除
        this.checkExcludedClasses(configurations, exclusions);
        // 从候选的配置类中移除被排除的配置类
        configurations.removeAll(exclusions);
        // 根据自动配置元数据对候选的配置类进行过滤
        configurations = this.filter(configurations, autoConfigurationMetadata);
        // 触发自动配置导入事件
        this.fireAutoConfigurationImportEvents(configurations, exclusions);
        // 返回包含需要导入的配置类和排除的配置类信息的AutoConfigurationEntry对象
        return new AutoConfigurationEntry(configurations, exclusions);
    }
}

这段代码的核心在于getCandidateConfigurations这个方法,目的是将所有需要自动配置的类导入到Sping容器中,将此方法进行断点追踪:

深度剖析SpringBoot自动配置原理,为什么SpringBoot能为我们做那么多东西,SpringBoot从入门到入魂,spring boot,java,后端
可以发现有124个配置被导入了,注意每个版本导入的配置不一样,注意区分,那么这些配置是从哪里来的呢?我们继续追踪getCandidateConfigurations的源码:

```java
/**
 * 获取候选的自动配置类列表。
 *
 * @param metadata   注解元数据,用于获取注解信息。
 * @param attributes 注解属性,用于获取属性信息。
 * @return 候选的自动配置类列表,从META-INF/spring.factories中加载配置。
 * @throws IllegalArgumentException 如果没有在META-INF/spring.factories中找到自动配置类,抛出该异常。
 */
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
    // 通过SpringFactoriesLoader从META-INF/spring.factories加载所有自动配置类的全限定类名
    List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.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;
}

这段代码用于获取候选的自动配置类列表,它通过SpringFactoriesLoader从META-INF/spring.factories文件中加载所有自动配置类的全限定类名。

META-INF/spring.factories是Spring Boot用于定义自动配置的配置文件,其中指定了各种自动配置类和相关配置信息。,这个文件的位置是在每个JAR包下,并不是每个包都会有,最核心的是下图中自动配置包:

深度剖析SpringBoot自动配置原理,为什么SpringBoot能为我们做那么多东西,SpringBoot从入门到入魂,spring boot,java,后端
上面的124个候选配置类全部都在此文件中:

# 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.cloud.CloudServiceConnectorsAutoConfiguration,\
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.elasticsearch.ReactiveElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveRestClientAutoConfiguration,\
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.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.elasticsearch.rest.RestClientAutoConfiguration,\
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.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

三. 按需开启自动配置

上面所有候选的自动配置中,并不是所有配置都会全部开启,SpringBoot会按需去开启自动配置。

SpringBoot将所有这些自动配置都会归结到xxxxAutoConfiguration.java中,比如关于AOP的自动配置类AopAutoConfiguration.java,那么SpringBoot是如何进行按需去开启自动配置的呢?

主要看这几个条件注解:

  1. @ConditionalOnClass: 当指定的类位于类路径上时,才会应用配置。可以用来根据类的存在与否来决定是否开启自动配置。

  2. @ConditionalOnBean: 当指定的Bean已经存在于Spring容器中时,才会应用配置。可以用来依赖其他Bean的存在与否来决定是否开启自动配置。

  3. @ConditionalOnMissingBean: 当指定的Bean不存在于Spring容器中时,才会应用配置。可以用来检查某个Bean是否缺失,从而决定是否开启自动配置。

  4. @ConditionalOnProperty: 当指定的配置属性满足条件时,才会应用配置。可以根据配置文件中的属性值来决定是否开启自动配置。

下面就用BatchAutoConfiguration.java来详细说明一下按需自动配置的过程的。先看BatchAutoConfiguration.java自动批处理配置的源码:

@Configuration(
    proxyBeanMethods = false
)
@ConditionalOnClass({JobLauncher.class, DataSource.class})
@AutoConfigureAfter({HibernateJpaAutoConfiguration.class})
@ConditionalOnBean({JobLauncher.class})
@EnableConfigurationProperties({BatchProperties.class})
@Import({BatchConfigurerConfiguration.class})
public class BatchAutoConfiguration {

下面来具体分析这段代码:

@Configuration(proxyBeanMethods = false)

默认情况下,proxyBeanMethodstrue,表示Spring会使用CGLIB代理来保证@Bean方法的调用,设置为false时,将禁用CGLIB代理,以用于增强性能。

@ConditionalOnClass({JobLauncher.class, DataSource.class})

当类路径下同时存在JobLauncherDataSource类时,才会启用该自动配置类。说明,当应用程序中同时使用了批处理(Batch)功能和数据源(数据库)时,这个自动配置类才会生效。

@AutoConfigureAfter({HibernateJpaAutoConfiguration.class})

HibernateJpaAutoConfiguration.java完成配置之后,批处理自动配置类将会生效。

@ConditionalOnBean({JobLauncher.class})

当Spring容器中存在JobLauncher这个Bean时,才会启用该自动配置类。

@EnableConfigurationProperties({BatchProperties.class})

表示启用BatchProperties类的配置属性支持。用于配置批处理相关的属性值。

@Import({BatchConfigurerConfiguration.class})

导入BatchConfigurerConfiguration配置类,进一步完成批处理的自动配置。

总结一下,只有全部满足以下全部条件,批处理这个类才会生效:

  • 类路径中存在JobLauncherDataSource类。
  • 应用程序已经定义了JobLauncher这个Bean。
  • HibernateJpaAutoConfiguration加载配置完成之后,自动配置类才会生效。
  • 启用了BatchProperties类的配置属性支持。
  • 可能会导入BatchConfigurerConfiguration配置类,用于进一步完成批处理的自动配置。

当上面的类校验完成之后,就会依次去执行内部含有@Bean定义的一些组件,导入Spring容器中,这里只分析一种方法,其他方法的分析方式是一样的。

/**
 * 创建并配置一个JobLauncherCommandLineRunner Bean,用于在应用程序启动时执行批处理作业。
 * 当满足以下条件时,该Bean会被创建:
 *   1. Spring容器中不存在JobLauncherCommandLineRunner Bean(@ConditionalOnMissingBean注解)。
 *   2. 配置属性中指定了"spring.batch.job.enabled"属性,并且值为"true"(@ConditionalOnProperty注解)。
 *   3. BatchProperties类中的配置属性"spring.batch.job.names"(作业名称列表)有值(非空字符串)时,会将该值设置到JobLauncherCommandLineRunner中。
 *   4. 如果"spring.batch.job.enabled"属性没有配置或没有指定值,将默认为"true"(matchIfMissing = true)。
 *
 * @param jobLauncher 用于启动批处理作业的JobLauncher Bean。
 * @param jobExplorer 用于探查已经运行过的作业的JobExplorer Bean。
 * @param jobRepository 用于管理作业实例的JobRepository Bean。
 * @param properties 用于配置批处理的BatchProperties对象。
 * @return 创建的JobLauncherCommandLineRunner Bean。
 */
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(
    prefix = "spring.batch.job",
    name = {"enabled"},
    havingValue = "true",
    matchIfMissing = true
)
public JobLauncherCommandLineRunner jobLauncherCommandLineRunner(JobLauncher jobLauncher, JobExplorer jobExplorer, JobRepository jobRepository, BatchProperties properties) {
    JobLauncherCommandLineRunner runner = new JobLauncherCommandLineRunner(jobLauncher, jobExplorer, jobRepository);
    String jobNames = properties.getJob().getNames();
    if (StringUtils.hasText(jobNames)) {
        runner.setJobNames(jobNames);
    }
    return runner;
}

当满足以下条件时,该Bean会被创建:

  • Spring容器中不存在JobLauncherCommandLineRunner这个Bean(@ConditionalOnMissingBean注解)。
  • 配置属性中指定了spring.batch.job.enabled属性,并且值为true@ConditionalOnProperty注解)。
  • BatchProperties类中的配置属性spring.batch.job.names(作业名称列表)有值(非空字符串)时,会将该值设置到JobLauncherCommandLineRunner中。
  • 如果spring.batch.job.enabled属性没有配置或没有指定值,将默认为truematchIfMissing = true)。

到这里,SpringBoot的自动配置原理基本上就结束了,下面就总结一下:文章来源地址https://www.toymoban.com/news/detail-644370.html

  1. SpringBoot会从META-INF/spring.factories文件中自动加载xxxxAutoConfiguration的所有配置类
  2. 每个配置类会按照特定的条件进行校验来进行按需加载,同时会默认绑定获取properties文件中的值
  3. 生效的配置类会在容器中配置很多的组件
  4. 当然这些组件我们可以自己进行配置(通过Java类或者配置文件中配置)

到了这里,关于深度剖析SpringBoot自动配置原理,为什么SpringBoot能为我们做那么多东西的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 指定了ip为什么还有自动配置ipv4?

    刚买了一天双网卡的主机,插上网线配置上网地址,发现指定了ip为什么还有自动配置ipv4? 将研究发现 应该是电脑启用了自动配置IPv4功能,导致了固定IP无法分配给电脑,尝试用命令关闭自动配置IPv4 功能:以管理员身份运行cmd.exe输入: netsh winsock reset catalog 回车输入: net

    2024年02月03日
    浏览(58)
  • 【C++】 为什么多继承子类重写的父类的虚函数地址不同?『 多态调用汇编剖析』

    👀 樊梓慕: 个人主页  🎥 个人专栏: 《C语言》 《数据结构》 《蓝桥杯试题》 《LeetCode刷题笔记》 《实训项目》 《C++》 《Linux》《算法》 🌝 每一个不曾起舞的日子,都是对生命的辜负 本篇文章主要是为了解答有关多态的那篇文章那块的一个奇怪现象,大家还记得这张

    2024年02月19日
    浏览(38)
  • (一)springboot实战——为什么是springboot?

    为什么是springboot?江湖夜雨,传说依旧,不懂springboot一技之长,如何混迹java圈,本节内容我们介绍一下spring的一些基本特性。尤其是springboot3的基本特性,使得我们更好的理解springboot3。 springboot的特点 -可以快速的创建一个独立的spring项目,取代老式的SSM项目 - 直接嵌入T

    2024年02月09日
    浏览(85)
  • 为什么自动驾驶需要5G?

    什么叫自动驾驶? 自动驾驶分为6个等级: Level 0: 人工驾驶,无驾驶辅助系统,仅提醒。 Level 1: 辅助人工驾驶,可实现单一的车速或转向控制自动化,仍由人工驾驶(如定速巡航、ACC)。 Level 2: 部分自动驾驶,可实现车速和转向控制自动化,驾驶员必须始终保持监控(

    2024年02月08日
    浏览(65)
  • Springboot启动原理和自动配置原理

    关于 springboot 启动流程和配置原理 很久就写了,不过没有详细补充 ,现在补充 —— 2023-08-05 BootstrapRegistryInitializer 是一个函数是接口 org.springframework.boot.BootstrapRegistry 接口 getSpringFactoriesInstances 加载工厂中组件实现方式 org.springframework.core.io.support.SpringFactoriesLoader#loadSpringFacto

    2023年04月25日
    浏览(48)
  • 深度学习过程中测试准确率先上升后下降是为什么?

    很典型的过拟合问题。 在训练过程中的验证准确率前上升,后下降,即在验证集上的表现先好后差。 数据相对模型来说比较简单,即模型的表达能力过剩。在初始训练阶段,模型逐渐开始学习到一些信息,因而在验证集上的表现是提升的,在到达某一点后,模型接着训练则

    2024年02月11日
    浏览(38)
  • 定期为什么不建议自动转存

    自动转存是银行一种资金周转方式,一般是指用户的定期存款到期之后,银行可自动将到期的存款本息按相同存期一并转存的行为,在存款过程中,一般不建议投资者自动转存,其主要原因如下: 1、资金支配受到限制 如果是三年期存款,投资者选择存款时自动转存,则在存

    2024年02月12日
    浏览(44)
  • 为什么需要自动化测试

    自动化的优势: 1.自动化可以代替手工大量地重复的工作,测试可以把大量的时间放在用例设计和新功能上边 2.自动化可以大量提升回归测试效率,特别适合敏捷开发 3.自动化可以大量地利用无人值守的时间去执行用例,特别适合非工作是爱你执行测试,工作时间分析测试用

    2024年02月13日
    浏览(67)
  • SpringBoot原理-自动配置-原理分析-源码跟踪

    SpringBootApplication 该注解标识在SpringBoot项目的启动类上,是SpringBoot中 最为重要 的注解,该注解由三个部分组成。 @SpringBootConfiguration:该注解与@Configuration注解作用一样,用来声明当前类为一个配置类 @ComponentScan:组件扫描,默认扫描当前启动类所在包及其子包 @EnableAutoConf

    2024年02月09日
    浏览(42)
  • 为什么深度学习网络越往后卷积核通道数越大

    在深度神经网络中,通常将前面的卷积层设计为 提取较为基础的特征(物理轮廓、边缘、颜色、纹理) ,后面的卷积层则负责 进一步提取更加高级的特征(和类别相关的抽象特征) 。因此,后面的卷积层需要更加复杂、抽象的特征表达能力,才能有效地提取更好的特征。 为了增

    2024年02月13日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包