1、SpringBoot是什么
要想了解spring启动流程的原理首先肯定要要知道什么是SpringBoot
Spring的话大家应该都知道,如果不知道的话可以去看下我之前发的博客 boot翻译过来就是启动的意思 SpringBoot就是启动Spring项目的一个工具,SpringBoot其实是依赖于Spring的,可以说SpringBoot是Spring的一个升级版本 它省略了Spring的很多的配置 这就是SpringBoot自身强大的自动装配功能,而且SpringBoot这个框架中内嵌了Tomcat,web的容器,集成了SpringMVC等等这框架,无需我们额外配置Tomcat
2、SpringBoot的优点是什么
-
简化的配置:Spring Boot 提供了自动配置的功能,能够根据项目的依赖和环境自动进行相应的配置。这极大地减少了开发人员的配置工作,使得项目的搭建和部署变得更加简单和高效。
-
内嵌式容器:Spring Boot 集成了多种内嵌式容器(如Tomcat、Jetty等),不需要额外部署应用服务器,可以直接运行应用程序。这样可以简化部署过程,减少了依赖和配置的复杂性。
-
自动化依赖管理:Spring Boot 的依赖管理功能可以自动解决版本冲突问题,并提供了许多常用的库和框架的默认依赖配置。开发人员只需声明所需的依赖,Spring Boot 就能负责版本和配置的管理,减轻了开发人员的负担。
-
提供了一系列的起步依赖:Spring Boot 提供了大量的起步依赖,这些依赖预配置了许多常用的库和框架,并自动处理它们之间的依赖关系。开发人员可以通过引入这些起步依赖,快速构建符合需求的应用程序。
3、SpringBoot启动原理
流程图:
创建一个SpringApplication对象,并调用了run方法
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
this.sources = new LinkedHashSet();
this.bannerMode = Mode.CONSOLE;
this.logStartupInfo = true;
this.addCommandLineProperties = true;
this.addConversionService = true;
this.headless = true;
this.registerShutdownHook = true;
this.additionalProfiles = Collections.emptySet();
this.isCustomEnvironment = false;
this.lazyInitialization = false;
this.applicationContextFactory = ApplicationContextFactory.DEFAULT;
this.applicationStartup = ApplicationStartup.DEFAULT;
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new LinkedHashSet(Arrays.asList(primarySources));
this.webApplicationType = WebApplicationType.deduceFromClasspath();
this.bootstrapRegistryInitializers = this.getBootstrapRegistryInitializersFromSpringFactories();
//获取所有初始化器
this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
//获取所有监听器
this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
//定位main方法
this.mainApplicationClass = this.deduceMainApplicationClass();
}
3.1:获取初始化器
跟踪进入getSpringFactoriesInstances方法
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {
ClassLoader classLoader = this.getClassLoader();
//获取所有初始化器的名称集合
Set<String> names = new LinkedHashSet(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
//根据名称集合实例化这些初始化器(通过反射)
List<T> instances = this.createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);
AnnotationAwareOrderComparator.sort(instances);
return instances;
}
从源码可以看出,该配置模块的主要使用到了SpringFactoriesLoader,即Spring工厂加载器,该对象提供了loadFactoryNames方法,SpringFactoriesLoader在META-INF/spring.factories配置文件里收集到文件中的类全名并返回一个类全名的数组,返回的类全名通过反射被实例化,就形成了具体的工厂实例,工厂实例来生成组件具体需要的bean。
3.2:获取初监听器
同样跟踪源码,发现其实监听器和初始化的操作是基本一样的,这里就不细说了
3.3:定位main方法
跟踪源码进入deduceMainApplicationClass
方法
private Class<?> deduceMainApplicationClass() {
try {
//通过创建运行时异常的方式获取栈
StackTraceElement[] stackTrace = (new RuntimeException()).getStackTrace();
StackTraceElement[] var2 = stackTrace;
int var3 = stackTrace.length;
//遍历获取main方法所在的类并且返回
for(int var4 = 0; var4 < var3; ++var4) {
StackTraceElement stackTraceElement = var2[var4];
if ("main".equals(stackTraceElement.getMethodName())) {
return Class.forName(stackTraceElement.getClassName());
}
}
} catch (ClassNotFoundException var6) {
}
return null;
}
4、Springboot启动类注解
4.1、@SpringBootApplication:
这是最常见的 Spring Boot 启动类注解。它是一个组合注解,包括了以下三个注解的功能:@Configuration
、@EnableAutoConfiguration
、@ComponentScan
。@SpringBootApplication
注解标识了一个配置类,并启用了自动配置和组件扫描。它通常位于应用程序的主类上
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
4.2、@Configuration:
这个注解表明该类是一个配置类,它可以包含 Bean 的定义和其他配置信息。
@Configuration
public class MyConfiguration {
// 配置一些 Bean
}
4.3、 @EnableAutoConfiguration:
这个注解用于启用 Spring Boot 的自动配置功能。它会根据应用程序的依赖和配置自动配置 Spring 应用程序的各个部分,如数据源、Web 容器等。
@EnableAutoConfiguration
public class MyAutoConfiguration {
// 自动配置的相关内容
}
4.4、@ComponentScan:
这个注解用于启用组件扫描,指定需要扫描的包路径。Spring Boot 将在指定的包及其子包中查找带有 @Component
及其衍生注解的类,并注册它们为 Spring Bean。
@ComponentScan(basePackages = "com.example.myapp")
public class MyComponentScanConfig {
// 组件扫描的相关配置
}
这些注解通常一起使用,以便配置和启动 Spring Boot 应用程序。主要的启动类上会标注
@SpringBootApplication
,而其他配置类可以用@Configuration
注解来定义,然后通过@ComponentScan
或其他配置方式将它们引入到应用程序中。