springboot 原理(如何启动)
springboot 近年来很火,因为他的一些特性。
springboot 特性
官方原话:
-
Create stand-alone Spring applications (能创建独立运行的应用)
-
Embed Tomcat, Jetty or Undertow directly (no need to deploy WAR files)(内嵌tomcat,jetty,underow容器)
-
Provide opinionated 'starter' dependencies to simplify your build configuration(能够编写自己的启动依赖通过简单配置)
-
Automatically configure Spring and 3rd party libraries whenever possible(自动集成spring或者第三方包)
-
Provide production-ready features such as metrics, health checks, and externalized configuration(提供生产特性,包括度量,健康检查等)
-
Absolutely no code generation and no requirement for XML configuration(无xml配置文件)
大概就是这些特性,极大的减少了XML配置和跟其他第三方集成这些痛病,让开发者只关注业务。
springboot 结构和依赖包
我们新建后的项目大概如下:pom
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
一般我们pom文件只要引用spring-boot-starter-web,这个是springboot web项目的
spring-boot-starter-actuator这个是做服务器健康检查的依赖,
上图可以看到,spring-boot-starter-web(2.3.1)下又引入了spring-core(5.2.1) ,spring-web,spring-web-mvn,spring-boot-starter-tomcat等等,这里看出,其实springboot的底层还是spring-core,web模块用的还是springmvc
springboot 启动过程
下面是spring的启动类。
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
很简单的一个类,加了个@SpringBootApplication的注解,然后SpringApplication.run(DemoApplication.class, args);将本身类作为参数,然后就可以启动了。
首先 @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
ComponentScan这个注解是spring的注解,作用是扫描包(包就是当前类下的包以及包下的所有包)下所有加了一些spring注解的类,把这些类加载到bean容器中,比如@Component和@Repository等,还有@Configuration的类也会扫描到,把类中的bean注解也会加载到容器中。
EnableAutoConfiguration这个注解是springboot的注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
这个是springboot的自动装配的开关,springboot能够自动装配其他第三方包也是这个注解的作用。
通过@Import引入的一个AutoConfigurationImportSelector实例,这个实例里有一段代码
private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
MultiValueMap<String, String> result = (MultiValueMap)cache.get(classLoader);
if (result != null) {
return result;
} else {
try {
Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");
LinkedMultiValueMap result = new LinkedMultiValueMap();
while(urls.hasMoreElements()) {
URL url = (URL)urls.nextElement();
UrlResource resource = new UrlResource(url);
Properties properties = PropertiesLoaderUtils.loadProperties(resource);
Iterator var6 = properties.entrySet().iterator();
while(var6.hasNext()) {
Entry<?, ?> entry = (Entry)var6.next();
String factoryTypeName = ((String)entry.getKey()).trim();
String[] var9 = StringUtils.commaDelimitedListToStringArray((String)entry.getValue());
int var10 = var9.length;
for(int var11 = 0; var11 < var10; ++var11) {
String factoryImplementationName = var9[var11];
result.add(factoryTypeName, factoryImplementationName.trim());
}
}
}
cache.put(classLoader, result);
return result;
} catch (IOException var13) {
throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var13);
}
}
}
这个就是这个类的主要作用,作用就是加载我们项目路径下META-INF/spring.factories的文件,我们看看这些文件大概什么样?
看到没有,这些就是springboot自动装配的原理和核心了,通过这个注解和AutoConfigurationImportSelector,启动时,spring就知道要初始化那些类,有些listener,还有那些配置类需要加载的。
很多第三方的jar包都是通过这种方式集成到我们的springboot的。随便找个第三方包
本文地址:https://blog.csdn.net/shrek11/article/details/107080049
上一篇: 深入理解Python中装饰器的用法