【SpringBoot】SpringBoot基础教程(2)
前言:
本文内容:第一个SpringBoot程序、IDEA快速创建、SpringBoot自动装配原理
推荐免费SpringBoot基础教程视频:[【狂神说Java】SpringBoot最新教程通俗易懂_哔哩哔哩_bilibili
第一个SpringBoot程序
搭建环境
- JDK1.8
- Maven3.6.1
- springBoot:最新版
- IDEA
官方提供了一个快速生成的网站,IDEA集成了这个网站。
SpringBoot快速搭建:Spring Initializr
搭建好的项目:helloworld.zip
将搭建好的项目导入IDEA即可
IDEA快速创建
-
New Project->选择Spring Initializr->Next 等待下载
注意:
如果这里spring.io加载速度过慢或者加载失败可以使用国内镜像
springboot中文镜像:Spring Initializr (springboot.io)
阿里云镜像(版本更新较慢):阿里云知行动手实验室-在浏览器沉浸式学习最新云原生技术 (aliyun.com)
-
填写包名、项目名、选择Maven、语言选择Java、Packaging选择jar、Java Version选择8 ->Next
-
勾选Web中的Spring Web支持->Next
-
选择好存放的地址,点击Finish
-
等待依赖下载完成即可
踩了一个小坑:IDEA中勾选了Maven->Work offine导致无法从服务器下载Jar包
如果下载好发现plugin报错,需要在本地maven仓库找到下载的对应版本替换即可(尤其是使用了国内镜像)
附上修改后可以运行的pom.xml
1 |
|
简单测试
-
新建
com.jokerdig.controller
包,然后新建HelloController.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20package com.jokerdig.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* @author Joker大雄
* @data 2022/7/11 - 16:04
**/
public class HelloController {
public String hello(){
return "Hello World";
}
} -
运行启动文件
Springboot01HelloworldApplication
-
访问地址
浏览器显示:Hello World
-
搭建成功
简单配置
-
修改端口号
修改
resources
文件夹下的application.properties
1
2# 更改端口号
server.port=8081 -
修改SpringBoot Banner
Spring Boot和终端命令行banner会让项目更有意思 bootschool.net
Spring Boot banner在线生成工具 bootschool.net
在网站生成后复制内容,并在
resources
文件夹下新建banner.txt
,粘贴复制的内容即可
SpringBoot自动装配原理
pom.xml
- spring-boot-dependencies:核心依赖在父工程中
- 我们在写或者引入一些SpringBoot依赖的时候,不需要指定版本,就是因为这些版本仓库
启动器
新版本启动器被放置在每一个单独启动器里了(之前是直接在pom.xml)
1 | <dependency> |
- 启动器就是SpringBoot的启动场景
- 例如启动
spring-boot-starter-web
,它会帮我们自动导入web环境所有的依赖 - SpringBoot会将所有的功能场景都变成一个个启动器
- 要使用什么功能,就只需要找到对应的启动器就可以了
starter
主程序
1 | package com.jokerdig; |
注解
-
@SpringBootApplication
标注这个类是一个SpringBoot的应用 -
@ComponentScan
扫描主启动类同级包 -
@SpringBootConfiguration
SpringBoot的配置@Configuration
Spring配置类@Component
这是Spring的组件
-
@EnableAutoConfiguration
自动配置-
@AutoConfigurationPackage
自动配置包@Import(AutoConfigurationPackages.Registrar.class)
自动配置包
-
@Import(AutoConfigurationImportSelector.class)
自动配置导入选择-
// 获取所有配置 configurations List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes); // getCandidateConfigurations 方法 protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) { List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(), 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; } // 1. 加载的工厂类最后返回了EnableAutoConfiguration 自动配置 // 通过EnableAutoConfiguration的注解标记SpringBoot主启动类的所有组件 protected Class<?> getSpringFactoriesLoaderFactoryClass() { return EnableAutoConfiguration.class; } // 2. loadFactoryNames加载工厂 public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) { String factoryTypeName = factoryType.getName(); return loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList()); // 调用了 loadSpringFactories方法 } // loadSpringFactories方法 private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) { MultiValueMap<String, String> result = cache.get(classLoader);// 缓存 若有缓存则直接返回 if (result != null) { return result; } try { // 通过枚举遍历URL 并通过类加载器(classLoader)获取所有资源 Enumeration<URL> urls = (classLoader != null ? classLoader.getResources(FACTORIES_RESOURCE_LOCATION) : ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION)); // 获取系统资源 result = new LinkedMultiValueMap<>(); while (urls.hasMoreElements()) { // 通过while循环遍历,hasMoreElements判断有没有更多元素 URL url = urls.nextElement(); UrlResource resource = new UrlResource(url); Properties properties = PropertiesLoaderUtils.loadProperties(resource);// 把url获取所有资源加载到Properties中 for (Map.Entry<?, ?> entry : properties.entrySet()) { String factoryTypeName = ((String) entry.getKey()).trim(); for (String factoryImplementationName : StringUtils.commaDelimitedListToStringArray((String) entry.getValue())) { result.add(factoryTypeName, factoryImplementationName.trim()); } } } cache.put(classLoader, result);// 最后put放置到缓存中 return result; } catch (IOException ex) { throw new IllegalArgumentException("Unable to load factories from location [" + FACTORIES_RESOURCE_LOCATION + "]", ex); } }
META-INF/spring.factories
:自动配置的核心文件 -
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration
-
-
自动装配原理分析流程图
小结
SpringBoot自动配置都在启动类中扫描并加载,扫描spring.factories
配置文件,所有的自动配置类都在该配置文件中,但是并不是都会生效,需要满足核心注解:@ConditionalOnXXX
的条件后才能生效(需要导入了对应的starter
才能生效)。
- SpringBoot在启动的时候,从类路径下
/META-INF/spring.factories
获取指定的值; - 将这些自动配置的类导入容器,自动配置就能生效;
- 以前我们需要自动配置的东西,现在SpringBoot帮我们做了;
- 整合JavaEE,解决方案和自动配置的内容都在
spring-boot-autoconfigure-2.3.0.RELEASE.jar
这个包下 - 它会把所有需要导入的组件,以类名的方式返回,这些组件被添加到容器中;
- 容器中也会存在非常多
XXXAutoConfiguration
的文件(@Bean),就是这些类给容器中导入了该场景需要的所有组件,并自动配置@Configuration
; - 有了自动配置类,免去了我们手动编写配置文件的工作;