抛出问题

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

大家可以看到,如上所示是一个很常见的SpringBoot启动类,我们可以看到仅仅使用了一个Main方法就启动了整个SpringBoot项目是不是很神奇,下面我们来仔细剖析以下这一段代码,这段代码中我们可以仔细地观察到最重要的两个部分,分别是@SpringBootApplication注解和SpringApplication这个类。

  • @SpringBootApplication注解
  • SpringApplication类

@SpringBootApplication注解剖析

打开这个@SpringBootApplication注解,如下所示

@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 { @AliasFor(annotation = EnableAutoConfiguration.class)
Class<?>[] exclude() default {}; @AliasFor(annotation = EnableAutoConfiguration.class)
String[] excludeName() default {}; @AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
String[] scanBasePackages() default {}; @AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
Class<?>[] scanBasePackageClasses() default {}; }

我们可以发现;我们可以在@SpringBootApplication注解中使用exclude(),excludeName(),scanBasePackages(),scanBasePackageClasses() 这四个方法来进行自定义我们需要排除装配的Bean,扫描包路径,扫描类路径。

搭眼一瞅,在@SpringBootApplication注解上还有下面那么多注解。

@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) })

这四个注解不用看,就是关于注解的一些定义

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited

@SpringBootConfiguration注解我们点进去看一下,发现是下面这个样子,@SpringBootConfiguration注解上又标注了@Configuration注解,想必在@Configuration注解上也标注了@Component注解,这不就是我们上一章节说的Spring的模式注解。总的来说嘛,SpringBootConfiguration注解的作用就是把类变成可以被Spring管理的Bean

结论 1 :也就是说标注@SpringBootApplication注解的类会成为Spring的Bean

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration { }

我们再来看一下@EnableAutoConfiguration,从名字上我们就可以看到“启用自动装配”的意思。那我们可要仔细看一下。从下面我们可以看到只有两个我们需要了解的注解,分别是@AutoConfigurationPackage@Import注解。

@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(AutoConfigurationPackages.Registrar.class)(上一章节有讲到);所以又点进去AutoConfigurationPackages.Registrar.class这个类,发现这个类又实现了两个接口ImportBeanDefinitionRegistrarDeterminableImports 在该类的实现方法中的PackageImport();最后终于发现了下面这段代码。

	PackageImport(AnnotationMetadata metadata) {
this.packageName = ClassUtils.getPackageName(metadata.getClassName());
}

结论 2 :SpringBoot默认会装配启动类路径的所有包下可装配的Bean;也就是说如果你把SpringBoot启动类放在一个单独的包中,则SpringBoot不会装配到你的其他Bean。这时候你就要使用@SpringBootApplicationscanBasePackages()方法进行另行配置。

此时@EnableAutoConfiguration注解仅仅就剩下@Import(AutoConfigurationImportSelector.class)没有看了,不过从注解上我们可以看到使用@Import注解,所以可以知道SpringBoot使用的是模块装配的接口实现方式。所以我么针对AutoConfigurationImportSelector这个类仔细剖析一下。AutoConfigurationImportSelector - > AutoConfigurationImportSelector.selectImports() ->getAutoConfigurationEntry() -> getCandidateConfigurations() ->SpringFactoriesLoader.loadFactoryNames() -> loadFactoryNames() ->loadSpringFactories() ; 哈哈果然源码不经扒;看下面源码;META-INF/spring.factories这不就是配置SpringBoot自动配置的文件嘛。

public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";

Enumeration<URL> urls = (classLoader != null ?
classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));

结论 3 :SpringBoot在启动时会自动加载Classpth路径下的META-INF/spring.factories文件,所以我们可以将需要自动配置的Bean写入这个文件,SPringBoot会替我们自动装配。这也正是配置SpringBoot自动配置的步骤。

SpringApplication类剖析

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

在Main方法中我们可以看到SpringApplication作为一个启动类来启动SpringBoot应用程序。那么SpringApplication类是如何进行启动整个应用程序的呢?

第一步:配置SpringBoot Bean来源

	public SpringApplication(Class<?>... primarySources) {
this(null, primarySources);
}

从SpringApplication类的构造方法中我们可以看到,这里传入了一个主Bean来源;因为我们将标注了@SpringBootApplication注解的LearnspringbootApplication.class传递了进来,所以@SpringBootApplication扫描到的Bean和自动装配的Bean会作为主Bean来源。当然我们可以调用该类的setSources()方法设置自己的SpringXML配置。

第二步 :自动推断SpringBoot的应用类型

this.webApplicationType = WebApplicationType.deduceFromClasspath();

从上面一句代码(既SpringApplication初始化方法中一行代码);我们观察deduceFromClasspath()方法可以看到,SpringBoot判断类路径下是否存在下面类进而判断SpringBoot的应用类型。三种类型分别是NONESERVLETREACTIVE 。当然我们也可以调用setWebApplicationType()自行设置。

	private static final String[] SERVLET_INDICATOR_CLASSES = { "javax.servlet.Servlet",
"org.springframework.web.context.ConfigurableWebApplicationContext" }; private static final String WEBMVC_INDICATOR_CLASS = "org.springframework."
+ "web.servlet.DispatcherServlet"; private static final String WEBFLUX_INDICATOR_CLASS = "org."
+ "springframework.web.reactive.DispatcherHandler"; private static final String JERSEY_INDICATOR_CLASS = "org.glassfish.jersey.servlet.ServletContainer"; private static final String SERVLET_APPLICATION_CONTEXT_CLASS = "org.springframework.web.context.WebApplicationContext"; private static final String REACTIVE_APPLICATION_CONTEXT_CLASS = "org.springframework.boot.web.reactive.context.ReactiveWebApplicationContext";

第三步:推断SpringBoot的引导类

this.mainApplicationClass = deduceMainApplicationClass();

从上面一句代码(既SpringApplication初始化方法中一行代码);我们可以通过deduceMainApplicationClass()方法可以看到SpringBoot根据Main 线程执行堆栈判断实际的引导类。(PS:存在一种情况就是标注@SpringBootApplication注解的并不是引导类情况)

	private Class<?> deduceMainApplicationClass() {
try {
StackTraceElement[] stackTrace = new RuntimeException().getStackTrace();
for (StackTraceElement stackTraceElement : stackTrace) {
if ("main".equals(stackTraceElement.getMethodName())) {
return Class.forName(stackTraceElement.getClassName());
}
}
}
catch (ClassNotFoundException ex) {
// Swallow and continue
}
return null;
}

第四步:加载应用上下文初始化器

setInitializers((Collection) getSpringFactoriesInstances(
ApplicationContextInitializer.class));

从上面一句代码(既SpringApplication初始化方法中一行代码);我们发现setInitializers()方法会调用getSpringFactoriesInstances() -> getSpringFactoriesInstances() -> getSpringFactoriesInstances() 该方法会使用SpringFactoriesLoader类记进行加载配置资源既META-INF/spring.factories,利用 Spring 工厂加载机制,实例化 ApplicationContextInitializer 实现类,并排序对象集合。并使用AnnotationAwareOrderComparator类的sort()方法进行排序。

	private <T> Collection<T> getSpringFactoriesInstances(Class<T> type,
Class<?>[] parameterTypes, Object... args) {
ClassLoader classLoader = getClassLoader();
// Use names and ensure unique to protect against duplicates
Set<String> names = new LinkedHashSet<>(
SpringFactoriesLoader.loadFactoryNames(type, classLoader));
List<T> instances = createSpringFactoriesInstances(type, parameterTypes,
classLoader, args, names);
AnnotationAwareOrderComparator.sort(instances);
return instances;
}

第五步 :加载应用事件监听器

setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));

从上面一句代码(既SpringApplication初始化方法中一行代码);从setListeners() 方法中可以看到该方法仍然调用getSpringFactoriesInstances()方法,不同的是利用 Spring 工厂加载META-INF/spring.factories,实例化 ApplicationListener 实现类,并排序对象集合

第六步:启动SpringApplication 运行监听器( SpringApplicationRunListeners )

SpringApplication类的run()方法中,我们可以看到下面代码getRunListeners()方法同样利用 Spring 工厂加载机制,读取 SpringApplicationRunListener 对象集合,并且封装到组合类

SpringApplicationRunListeners对象中并启动运行监听器。

		SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting();

第七步:监听SpringBoot/Spring事件

Spring Boot 通过 SpringApplicationRunListener 的实现类 EventPublishingRunListener 利用 Spring Framework 事件

API ,广播 Spring Boot 事件。

第八步:创建SpringBoot的应用上下文

context = createApplicationContext();

SpringApplication类的run()方法中,我们可看到createApplicationContext()根据第二步推断的SpringBoot应用类型创建相应的上下文。

	protected ConfigurableApplicationContext createApplicationContext() {
Class<?> contextClass = this.applicationContextClass;
if (contextClass == null) {
try {
switch (this.webApplicationType) {
case SERVLET:
contextClass = Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS);
break;
case REACTIVE:
contextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS);
break;
default:
contextClass = Class.forName(DEFAULT_CONTEXT_CLASS);
}
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Unable create a default ApplicationContext, "
+ "please specify an ApplicationContextClass",
ex);
}
}
return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);
}

根据推断的SpringBoot应用类型创建下面三种之一的上下文

	public static final String DEFAULT_CONTEXT_CLASS = "org.springframework.context."
+ "annotation.AnnotationConfigApplicationContext"; public static final String DEFAULT_SERVLET_WEB_CONTEXT_CLASS = "org.springframework.boot."
+ "web.servlet.context.AnnotationConfigServletWebServerApplicationContext"; public static final String DEFAULT_REACTIVE_WEB_CONTEXT_CLASS = "org.springframework."
+ "boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext";

第九步:创建 Environment

ConfigurableEnvironment environment = prepareEnvironment(listeners,
applicationArguments);
configureIgnoreBeanInfo(environment);

SpringApplication类的run()方法中,我们可看到prepareEnvironment()根据第二步推断的SpringBoot应用类型创建相应的上下文。创建不同的Environment 。从下面可以看到他们分别是StandardServletEnvironmentStandardReactiveWebEnvironmentStandardEnvironment

	private ConfigurableEnvironment getOrCreateEnvironment() {
if (this.environment != null) {
return this.environment;
}
switch (this.webApplicationType) {
case SERVLET:
return new StandardServletEnvironment();
case REACTIVE:
return new StandardReactiveWebEnvironment();
default:
return new StandardEnvironment();
}
}

结论

  1. 标注@SpringBootApplication注解的类会成为Spring的Bean

  2. SpringBoot默认会装配启动类路径的所有包下可装配的Bean;也就是说如果你把SpringBoot启动类放在一个单独的包中,则SpringBoot不会装配到你的其他Bean。这时候你就要使用@SpringBootApplicationscanBasePackages()方法进行另行配置。

  3. SpringBoot在启动时会自动加载Classpth路径下的META-INF/spring.factories文件,所以我们可以将需要自动配置的Bean写入这个文件。同样SpringBoot也会扫描Jar包中的META-INF/spring.factories文件;例如当导入spring-boot-starter起步依赖的时候,并且启用了自动装配注解@EnableAutoConfiguration,就将会替我们自动装配如如下类;如果满足条件的话。

    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.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.reactor.core.ReactorCoreAutoConfiguration,\
    org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration,\
    org.springframework.boot.autoconfigure.security.servlet.SecurityRequestMatcherProviderAutoConfiguration,\
    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.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

该教程所属Java工程师之SpringBoot系列教程,本系列相关博文目录 Java工程师之SpringBoot系列教程前言&目录

SpringBoot SpringApplication底层源码分析与自动装配的更多相关文章

  1. springboot整合mybatis源码分析

    springboot整合mybatis源码分析 本文主要讲述mybatis在springboot中是如何被加载执行的,由于涉及的内容会比较多,所以这次只会对调用关系及关键代码点进行讲解,为了避免文章太 ...

  2. List-LinkedList、set集合基础增强底层源码分析

    List-LinkedList 作者 : Stanley 罗昊 [转载请注明出处和署名,谢谢!] 继上一章继续讲解,上章内容: List-ArreyLlist集合基础增强底层源码分析:https:// ...

  3. Vector总结及部分底层源码分析

    Vector总结及部分底层源码分析 1. Vector继承的抽象类和实现的接口 Vector类实现的接口 List接口:里面定义了List集合的基本接口,Vector进行了实现 RandomAcces ...

  4. List-ArrayList集合基础增强底层源码分析

    List集合基础增强底层源码分析 作者:Stanley 罗昊 [转载请注明出处和署名,谢谢!] 集合分为三个系列,分别为:List.set.map List系列 特点:元素有序可重复 有序指的是元素的 ...

  5. LInkedList总结及部分底层源码分析

    LInkedList总结及部分底层源码分析 1. LinkedList的实现与继承关系 继承:AbstractSequentialList 抽象类 实现:List 接口 实现:Deque 接口 实现: ...

  6. Spring Ioc源码分析系列--自动注入循环依赖的处理

    Spring Ioc源码分析系列--自动注入循环依赖的处理 前言 前面的文章Spring Ioc源码分析系列--Bean实例化过程(二)在讲解到Spring创建bean出现循环依赖的时候并没有深入去分 ...

  7. tomcat源码--springboot整合tomcat源码分析

    1.测试代码,一个简单的springboot web项目:地址:https://gitee.com/yangxioahui/demo_mybatis.git 一:tomcat的主要架构:1.如果我们下 ...

  8. Servlet和Tomcat底层源码分析

    Servlet 源码分析   Servlet 结构图 Servlet 和 ServletConfig 都是顶层接口,而 GenericServlet 实现了这两个顶层接口,然后HttpServlet ...

  9. JAVA ArrayList集合底层源码分析

    目录 ArrayList集合 一.ArrayList的注意事项 二. ArrayList 的底层操作机制源码分析(重点,难点.) 1.JDK8.0 2.JDK11.0 ArrayList集合 一.Ar ...

随机推荐

  1. 为什么要把session存入数据库

    比如网易的通行证,一个session能进入很多的网易下的网站

  2. e591. Drawing Simple Text

    See also e575 The Quintessential Drawing Program. public void paint(Graphics g) { // Set the desired ...

  3. 转载:Create a Flash Login System Using PHP and MySQL

    本文共两部分: 1. http://dev.tutsplus.com/tutorials/create-a-flash-login-system-using-php-and-mysql-part-1- ...

  4. 原生js版ajax请求

    function getXMLHttpRequest() { var xhr; if(window.ActiveXObject) { xhr= new ActiveXObject("Micr ...

  5. ms-SQL 递归调用

    ----递归函数-------------------------------------------------------------------------- create function d ...

  6. 【Graphlab】

    https://dato.com/ graphlab

  7. php 在windows下配置虚拟目录的方法

    1.先找到apache的配置文件 httpd.conf 找如如下代码: # Virtual hosts#Include conf/extra/httpd-vhosts.conf 把# Include ...

  8. 在线学习angularjs2

    官网给的学习教程(需要FQ) http://campus.codeschool.com/courses/accelerating-through-angular-2/contents

  9. Dubbo注册中心Zookeeper安装步骤

    第一步:安装jdk 第二步:上传zookeeper至Linux 第三步:解压zookeeper安装包(/soft目录是我在根目录下建立的一个用户存放上传安装包的目录),解压命令tar -xvf /so ...

  10. 使用 XPath

    XPath 简介: (1) 前面我们爬取一个网页,都是使用正则表达式来提取想要的信息,但是这种方式比较复杂,一旦有一个地方写错,就匹配不出来了,因此我们可以使用 XPath 来进行提取(2) XPat ...