0%

【SpringBoot】了解SpringBoot

通过稍微查看源码,对SpringBoot进行了解

一、pom.xml文件

  • pom.xml有个父项目为spring-boot-starter-parent
  • spring-boot-starter-parent也有一个父项目spring-boot-dependencies

1.1 pom.xml

  • 里面配置启动器依赖:spring-boot-starter-XXXX,也就是SpringBoot的启动场景
  • 举例:spring-boot-starter-web,他会帮我们自动导入web环境所有的依赖
  • springboot将所有的功能场景,都变成一个个启动器。需要相应的功能,则需要使用相应的启动器

1.2 spring-boot-starter-parent

  • 里面配置了资源插件,来过滤文件内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<resources>
<resource>
<directory>${basedir}/src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/application*.yml</include>
<include>**/application*.yaml</include>
<include>**/application*.properties</include>
</includes>
</resource>
<resource>
<directory>${basedir}/src/main/resources</directory>
<excludes>
<exclude>**/application*.yml</exclude>
<exclude>**/application*.yaml</exclude>
<exclude>**/application*.properties</exclude>
</excludes>
</resource>
</resources>
  • 里面也配置了一大堆插件

1.3 spring-boot-dependencieslim

  • 里面是管理SpringBoot的核心依赖,存放着各种各样的版本
  • 称此为版本仓库,因为此版本仓库,所以我们引入依赖时不需要指定版本

二、主程序XxxxApplication

2.1 主程序

1
2
3
4
5
6
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
  • 主程序需要关注的有:
    • 注解@SpringBootApplication
    • SpringApplication类

2.2 @SpringBootApplication注解

  • (1)点进@SpringBootApplication
1
2
3
4
5
6
7
8
SpringBootApplication注解
//省略了元注解
@SpringBootConfiguration //SpringBoot的配置类
@EnableAutoConfiguration //自动配置
@ComponentScan(excludeFilters = {@Filter(type = FilterType.CUSTOM,classes = {TypeExcludeFilter.class}), //组件扫描
@Filter(type = FilterType.CUSTOM, classes = {AutoConfigurationExcludeFilter.class})
}
)//组件扫描
  • (2)点进@SpringBootConfiguration(springboot配置类)
1
2
3
SpringBootConfiguration注解
//省略了元注解
@Configuration //Spring配置类
  • 总结:@SpringBootConfiguration只是一个简单配置类

  • (3)点进@EnableAutoConfiguration
1
2
3
4
EnableAutoConfiguration注解
//省略了元注解
@AutoConfigurationPackage //自动配置包
@Import(AutoConfigurationImportSelector.class) //自动配置选择器导入
  • (4)点进@AutoConfigurationPackage
1
2
AutoConfigurationPackage注解
@Import(AutoConfigurationPackages.Registrar.class) //自动配置`包注册`
  • (5)点进AutoConfigurationImportSelector.class
1
2
3
4
5
6
7
8
9
10
11
12
13
14
protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
}
AnnotationAttributes attributes = getAttributes(annotationMetadata);
List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes); //获取候选的配置
configurations = removeDuplicates(configurations);
Set<String> exclusions = getExclusions(annotationMetadata, attributes);
checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
configurations = getConfigurationClassFilter().filter(configurations);
fireAutoConfigurationImportEvents(configurations, exclusions);
return new AutoConfigurationEntry(configurations, exclusions);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
点进获取候选配置方法getCandidateConfigurations()
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(), //getSpringFactoriesLoaderFactoryClass()获得加载类
getBeanClassLoader());
Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you " //如果配置为空,找不到META-INF/spring.factories,此为自动配置的核心文件
+ "are using a custom packaging, make sure that file is correct.");
return configurations;
}


protected Class<?> getSpringFactoriesLoaderFactoryClass() {
return EnableAutoConfiguration.class; //标记为@EnableAutoConfiguration的类启动资源
}

//@SpringBootApplication注解上,标记了@EnableAutoConfiguration,所以被SpringBootApplication标记的类的所有资源会导入
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
String factoryTypeName = factoryType.getName();
return (List)loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList());
}

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");//获取资源放在urls里
LinkedMultiValueMap result = new LinkedMultiValueMap();

while(urls.hasMoreElements()) { //判断是否含有更多元素,循环遍历资源,并保存着Properties类中
URL url = (URL)urls.nextElement();
UrlResource resource = new UrlResource(url);
Properties properties = PropertiesLoaderUtils.loadProperties(resource); //有,更多元素就封装到properties类里面
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的核心文件

2.3 查看spring.factories

  • 文件所在位置:org\springframework\boot\spring-boot-autoconfigure\2.3.4.RELEASE\spring-boot-autoconfigure-2.3.4.RELEASE.jar!\META-INF\spring.factories
  • spring.factories里面全是SpringBoot为我们配置的配置类,名字为xxxxAutoConfiguration
  • 分析其中的一个自动配置类
1
2
3
4
5
6
7
8
9
10
@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class,
ValidationAutoConfiguration.class })
public class WebMvcAutoConfiguration {

}
  • @ConditionalOnXxxx注解进行判断,如果过条件符合才会加载此自动类,通过pom.xml导入相关的启动器依赖,来满足条件,进行自动装配

2.4 main方法

  • (1)表面形式:
    • SpringApplication.run(Application.class, args),调用SpringApplication的静态方法run,利用反射进行运行
  • (2)内部形式
    • 1、推断应用的类型是普通的项目还是web项目
    • 2、查找并加载所有可用的初始化器,设置到initalizer属性中
    • 3、找出所有的应用程序监听器,设置到listeners
    • 4、推断并设置mian方法的定义类,找到运行的主类