zoukankan      html  css  js  c++  java
  • SpringBoot自动装配原理

    用过spring Boot的小伙伴都会知道它的自动配置,毕竟spring Boot的两个重要策略就是开箱即用和约定优于配置。可是,开发应用时,程序怎么知道我们需要加载那些框架呢。

    正常的springBoot的starter启动入口

    @SpringBootApplication注解就是指明当前当前为SpringBoot应用,点进去之后会发现如下

    这时就会发现@SpringBootApplication注解相当于这些注解的总和,其中@EnableAutoConfiguration注解就是自动配置的注解,在点进@EnableAutoConfiguration注解就会发现

    这里导入了AutoConfigurationImportSelector类的是实例,点进这个类查看其源码就会发现它实现的具体原理,在这个类中,AutoConfigurationImportSelector类实现了DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered这个几个接口,和包含了三个静态内部类,分别是 AutoConfigurationEntry ,AutoConfigurationGroup ,ConfigurationClassFilter。AutoConfigurationImportSelector类会先执行getImportGroup()这个方法,这个方法是实现了DeferredImportSelector接口的方法

    public Class<? extends Group> getImportGroup() {
              //返回的是当前类的AutoConfigurationGroup内部类的实例
            return AutoConfigurationImportSelector.AutoConfigurationGroup.class;
        }

     查看静态内部类AutoConfigurationGroup的源码

    //该内部类实现了DeferredImportSelector 的 Group
    private static class AutoConfigurationGroup implements Group, BeanClassLoaderAware, BeanFactoryAware, ResourceLoaderAware {
            private final Map<String, AnnotationMetadata> entries = new LinkedHashMap();
            private final List<AutoConfigurationImportSelector.AutoConfigurationEntry> autoConfigurationEntries = new ArrayList();
            private ClassLoader beanClassLoader;
            private BeanFactory beanFactory;
            private ResourceLoader resourceLoader;
            private AutoConfigurationMetadata autoConfigurationMetadata;
    
            private AutoConfigurationGroup() {
            }
    
            public void setBeanClassLoader(ClassLoader classLoader) {
                this.beanClassLoader = classLoader;
            }
    
            public void setBeanFactory(BeanFactory beanFactory) {
                this.beanFactory = beanFactory;
            }
    
            public void setResourceLoader(ResourceLoader resourceLoader) {
                this.resourceLoader = resourceLoader;
            }
             /**
             *  
             **/
            public void process(AnnotationMetadata annotationMetadata, DeferredImportSelector deferredImportSelector) {
                //该方法为判断第一个参数是否为真,如果为假的时候会报出中断异常,报错内容为后面的信息
               Assert.state(deferredImportSelector instanceof AutoConfigurationImportSelector, () -> {
                 //报错时,会报出以下错误
                    return String.format("Only %s implementations are supported, got %s", AutoConfigurationImportSelector.class.getSimpleName(), deferredImportSelector.getClass().getName());
                });
                //调用了getAutoConfigurationEntry这个方法,会获取各个包中/META-INF/spring.factories中的配置,这个位置是引入了SPI机制,进行过滤和排除处理,引入配置类和排除配置类,返回最终需要的配置类
                AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = ((AutoConfigurationImportSelector)deferredImportSelector).getAutoConfigurationEntry(annotationMetadata);
                //将筛选出的用到的自动配置项放入到autoConfigurationEntries列表中
                this.autoConfigurationEntries.add(autoConfigurationEntry);
                //得到一个自动配置项的名称组成的迭代器
                Iterator var4 = autoConfigurationEntry.getConfigurations().iterator();
    
                while(var4.hasNext()) {
                    //获取自动配置项的名称
                    String importClassName = (String)var4.next();
                    //向其中添加键值对时,先判断是否其已存在,如果已存在将不会进行覆盖
                    this.entries.putIfAbsent(importClassName, annotationMetadata);
                }
    
            }
            /**
            *   处理单独的配置的导入和到处
            **/
            public Iterable<Entry> selectImports() {
               //判断autoConfigurationEntries列表是否有值
                if (this.autoConfigurationEntries.isEmpty()) {
                    return Collections.emptyList();
                } else {
                     //得到自定义的一些需要配置
                    Set<String> allExclusions = (Set)this.autoConfigurationEntries.stream().map(AutoConfigurationImportSelector.AutoConfigurationEntry::getExclusions).flatMap(Collection::stream).collect(Collectors.toSet());
                     //得到系统所有的配置
                    Set<String> processedConfigurations = (Set)this.autoConfigurationEntries.stream().map(AutoConfigurationImportSelector.AutoConfigurationEntry::getConfigurations).flatMap(Collection::stream).collect(Collectors.toCollection(LinkedHashSet::new));
                    //从所有配置中去除需要过滤掉的配置
                    processedConfigurations.removeAll(allExclusions);
                    //将自定义需要引入的配置返回
                    return (Iterable)this.sortAutoConfigurations(processedConfigurations, this.getAutoConfigurationMetadata()).stream().map((importClassName) -> {
                        return new Entry((AnnotationMetadata)this.entries.get(importClassName), importClassName);
                    }).collect(Collectors.toList());
                }
            }
    
            private AutoConfigurationMetadata getAutoConfigurationMetadata() {
                if (this.autoConfigurationMetadata == null) {
                    this.autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
                }
    
                return this.autoConfigurationMetadata;
            }
    
            private List<String> sortAutoConfigurations(Set<String> configurations, AutoConfigurationMetadata autoConfigurationMetadata) {
                return (new AutoConfigurationSorter(this.getMetadataReaderFactory(), autoConfigurationMetadata)).getInPriorityOrder(configurations);
            }
    
            private MetadataReaderFactory getMetadataReaderFactory() {
                try {
                    return (MetadataReaderFactory)this.beanFactory.getBean("org.springframework.boot.autoconfigure.internalCachingMetadataReaderFactory", MetadataReaderFactory.class);
                } catch (NoSuchBeanDefinitionException var2) {
                    return new CachingMetadataReaderFactory(this.resourceLoader);
                }
            }
        }

    在上面这段代码中,为了加载配置项调用了一个重要方法 getAutoConfigurationEntry,这个方法

     protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
            if (!this.isEnabled(annotationMetadata)) {                                                                                              
                return EMPTY_ENTRY;
            } else {
              //获取注解元数据的属性
                AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
              //获取自动配置的类,在这个位置调用了getCandidateConfigurations方法,此方法为了处理加载配置
                List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
              //去除list列表中重复项,这里采用的LinkedHashSet列表的特性来处理重复的
                configurations = this.removeDuplicates(configurations);
              //获取单独配置的加载项,这个位置调用了getExclusions方法进行处理的
                Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
              //检查是否存在要排除配置项
                this.checkExcludedClasses(configurations, exclusions);
              //去除要删除的配置项
                configurations.removeAll(exclusions);
              //调用ConfigurationClassFilter静态内部类的filter过滤器,将用不到的配置项去掉
                configurations = this.getConfigurationClassFilter().filter(configurations);
              //触发自动化配置的导入事件
                this.fireAutoConfigurationImportEvents(configurations, exclusions);
                return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions);
            }
        }

    上面的类中调用了 getCandidateConfigurations方法,该方法实现了SPI机制,此方法的源码为:

       protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
         //调用了SpringFactoriesLoader类中的loadFactoryNames方法,用于加载所有的配置项
            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类中的loadFactoryNames方法源码

     public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
            ClassLoader classLoaderToUse = classLoader;
       //如果传递的类加载器为空,则使用SpringFactoriesLoader类加载器
            if (classLoader == null) {
                classLoaderToUse = SpringFactoriesLoader.class.getClassLoader();
            }
         //此时的factoryTypeName的值为org.springframework.boot.autoconfigure.EnableAutoConfiguration
            String factoryTypeName = factoryType.getName();
          //loadSpringFactories方法是获取指定接口的实现类对象。getOrDefault是Map类下的方法,意思是根据键对应的值不为空,则返回该值,为空返回默认值
            return (List)loadSpringFactories(classLoaderToUse).getOrDefault(factoryTypeName, Collections.emptyList());
        }

    由上面一段代码可知,主要是由loadSpringFactories方法处理的,查看loadSpringFactories方法代码

     private static Map<String, List<String>> loadSpringFactories(ClassLoader classLoader) {
            Map<String, List<String>> result = (Map)cache.get(classLoader);
            if (result != null) {
                return result;
            } else {
                HashMap result = new HashMap();
    
                try {
                  //扫描所有包路径下的META-INF/spring.factories文件
                    Enumeration urls = classLoader.getResources("META-INF/spring.factories");
    
                    while(urls.hasMoreElements()) {
                      //拿出其中一个包路径下的META-INF/spring.factories文件
                        URL url = (URL)urls.nextElement();
                      //根据META-INF/spring.factories文件问价路径获得资源
                        UrlResource resource = new UrlResource(url);
                      //将响应资源包装成Properties对象
                        Properties properties = PropertiesLoaderUtils.loadProperties(resource);
                      //将对象内容进行迭代
                        Iterator var6 = properties.entrySet().iterator();
    
                        while(var6.hasNext()) {
                            Entry<?, ?> entry = (Entry)var6.next();
                          //获取Properties对象中的key值
                            String factoryTypeName = ((String)entry.getKey()).trim();
                          //获取Properties对象中的value值,使用逗号为分隔符转化数组,数组内的每个元素都是配置类的完全限制名
                            String[] factoryImplementationNames = StringUtils.commaDelimitedListToStringArray((String)entry.getValue());
                            String[] var10 = factoryImplementationNames;
                            int var11 = factoryImplementationNames.length;
                           //将数组转化为集合
                            for(int var12 = 0; var12 < var11; ++var12) {
                                String factoryImplementationName = var10[var12];
                                ((List)result.computeIfAbsent(factoryTypeName, (key) -> {
                                    return new ArrayList();
                                })).add(factoryImplementationName.trim());
                            }
                        }
                    }
                   //将Properties对象中的key值和配置类组成的list集合存入到resultMap中
                    result.replaceAll((factoryType, implementations) -> {
                        return (List)implementations.stream().distinct().collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));
                    });
                    cache.put(classLoader, result);
                    return result;
                } catch (IOException var14) {
                    throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var14);
                }
            }
        }

    上面的源码中多次提到spring.factories文件,选择一个包下的spring.factories文件内容展示。当一个键有多个值时,就用逗号(,)分隔,利用反斜杠(\)进行换行

    # 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
    
    # Environment Post Processors
    org.springframework.boot.env.EnvironmentPostProcessor=\
    org.springframework.boot.autoconfigure.integration.IntegrationPropertiesEnvironmentPostProcessor
    
    # 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.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
    
    # 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.jooq.NoDslContextBeanFailureAnalyzer,\
    org.springframework.boot.autoconfigure.r2dbc.ConnectionFactoryBeanCreationFailureAnalyzer,\
    org.springframework.boot.autoconfigure.r2dbc.MissingR2dbcPoolDependencyFailureAnalyzer,\
    org.springframework.boot.autoconfigure.r2dbc.MultipleConnectionPoolConfigurationsFailureAnalzyer,\
    org.springframework.boot.autoconfigure.r2dbc.NoConnectionFactoryBeanFailureAnalyzer,\
    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
    
    # DataSource initializer detectors
    org.springframework.boot.sql.init.dependency.DatabaseInitializerDetector=\
    org.springframework.boot.autoconfigure.flyway.FlywayMigrationInitializerDatabaseInitializerDetector
    
    # Depends on database initialization detectors
    org.springframework.boot.sql.init.dependency.DependsOnDatabaseInitializationDetector=\
    org.springframework.boot.autoconfigure.batch.JobRepositoryDependsOnDatabaseInitializationDetector,\
    org.springframework.boot.autoconfigure.quartz.SchedulerDependsOnDatabaseInitializationDetector,\
    org.springframework.boot.autoconfigure.session.JdbcIndexedSessionRepositoryDependsOnDatabaseInitializationDetector
    
    生于忧患,死于安乐
  • 相关阅读:
    hdu-1862 EXCEL排序
    hdu-1754 I Hate It
    hdu-1538 A Puzzle for Pirates
    在Window下安装Linux (ubuntu-16.04.2)
    Python爬虫--简单的单词查询
    Linux下MySQL在知道密码的情况下修改密码
    Linux下忘记MySQL密码的解决方法和输入mysqld_safe --skip-grant-tables &后无法进入MySQL的解决方法
    Python的下载及安装
    在Netbeans的项目中添加JDBC驱动程序
    Mac下截屏方法
  • 原文地址:https://www.cnblogs.com/songlove/p/15641480.html
Copyright © 2011-2022 走看看