一、SpringBoot
1、介绍
springboot 是 spring 家族的一个项目,他的目标是提高使用者的开发效率。在帮助开发者快速并且更简单的构建项目。它使用习惯优于配置的理念让你的项目快速运行起来,使用Spring Boot很容易创建一个独立运行(运行jar,内置Servlet容器,Tomcat、jetty)、准生产级别的基于Spring框架的项目,使用SpringBoot框架,你可以不用或者只需要很少的配置文件。
2、核心功能
-
独立运行的Spring项目:可以以jar包形式独立运行,通过java -jar xx.jar即可运行。
-
内嵌Servlet容器:可以选择内嵌Tomcat、Jetty等。
-
提供starter简化maven配置:一个maven项目,使用了spring-boot-starter-web时,会自动加载Spring Boot的依赖包。
-
自动配置Spring:Spring Boot会根据在类路径中的jar包、类,为jar包中的类自动配置Bean。
-
准生产的应用监控:提供基于http、ssh、telnet对运行时的项目进行监控。
3、优点
-
为所有Spring开发者更快的入门
-
开箱即用,提供各种默认配置来简化项目配置
-
内嵌式容器简化Web项目
-
没有冗余代码生成和XML配置的要求
二、SpringBoot项目搭建
-
创建一个新项目
-
选择spring initalizr , 可以看到默认就是去官网的快速构建工具那里实现
-
填写项目信息
-
选择初始化的组件(初学勾选 Web 即可)
-
填写项目路径
-
等待项目构建成功
项目目录结构
启动SpringbootApplication,打开http://localhost:8080/
HelloWorrl程序
编写一个http接口
1、在主程序的同级目录下,新建一个controller包,一定要在同级目录下,否则识别不到
2、在包中新建一个HelloController类
访问http://localhost:8080/hello
三、SpringBoot运行原理
springboot启动流程
任何一个Spring Boot项目,都会用到如下的启动类SpringbootApplication
其中@SpringBootApplication注解是springboot的核心注解,本质是一个组合注解
有三个重要注解,也可以说@SpringBootApplication = (默认属性)@Configuration + @EnableAutoConfiguration + @ComponentScan
1、@SpringBootApplication
先看SpringBoot的主配置类,有一个main方法运行了一个run()方法,在run方法中必须要传入一个被@SpringBootApplication注解的类。
点击进去@SpringBootApplication注解
其中:
-
@SpringBootConfiguration:我们点进去以后可以发现底层是Configuration注解,说白了就是支持JavaConfig的方式来进行配置(使用Configuration配置类等同于XML文件)。
-
@EnableAutoConfiguration:开启自动配置功能
-
@ComponentScan:即扫描注解,默认是扫描当前类下的package。将@Controller/@Service/@Component/@Repository等注解加载到IOC容器中。
所以,Application类可以这样写:
2、@EnableAutoConfiguration
EnableAutoConfiguration注解会自动载入应用程序所需要的所有默认配置。点开EnableAutoConfiguration注解
-
@AutoConfigurationPackage:自动配置包
-
AutoConfigurationImportSelector :自动配置导入选择器
-
@Import({AutoConfigurationImportSelector.class}):给IOC容器导入组件
(1)、@AutoConfigurationPackage
AutoConfigurationPackage注解会成自动配置包。点击AutoConfigurationPackage注释
-
@import :Spring底层注解@import , 给容器中导入一个组件
-
Registrar.class 作用:将主启动类的所在包及包下面所有子包里面的所有组件扫描到Spring容器 ;
点击AutoConfigurationPackage注解中
在默认的情况下就是将:主配置类(@SpringBootApplication)的所在包及其子包里边的组件扫描到Spring容器中。
(2)、AutoConfigurationImportSelector.class
点击AutoConfigurationImportSelector.class,有这样一个方法
// 获得候选的配置
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
//这里的getSpringFactoriesLoaderFactoryClass()方法
//返回的就是我们最开始看的启动自动导入配置文件的注解类;EnableAutoConfiguration
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;
}
这个方法又调用了SpringFactoriesLoader类的静态方法,进入SpringFactoriesLoader类loadFactoryNames() 方法
public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
ClassLoader classLoaderToUse = classLoader;
if (classLoaderToUse == null) {
classLoaderToUse = SpringFactoriesLoader.class.getClassLoader();
}
String factoryTypeName = factoryType.getName();
//这里它又调用了 loadSpringFactories 方法
return loadSpringFactories(classLoaderToUse).getOrDefault(factoryTypeName, Collections.emptyList());
}
点击查看 loadSpringFactories 方法
private static Map<String, List<String>> loadSpringFactories(ClassLoader classLoader) {
//获得classLoader , 我们返回可以看到这里得到的就是EnableAutoConfiguration标注的类本身
Map<String, List<String>> result = cache.get(classLoader);
if (result != null) {
return result;
}
result = new HashMap<>();
try {
//去获取一个资源 "META-INF/spring.factories"
Enumeration<URL> urls = classLoader.getResources(FACTORIES_RESOURCE_LOCATION);
//将读取到的资源遍历,封装成为一个Properties
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
UrlResource resource = new UrlResource(url);
Properties properties = PropertiesLoaderUtils.loadProperties(resource);
for (Map.Entry<?, ?> entry : properties.entrySet()) {
String factoryTypeName = ((String) entry.getKey()).trim();
String[] factoryImplementationNames =
StringUtils.commaDelimitedListToStringArray((String) entry.getValue());
for (String factoryImplementationName : factoryImplementationNames) {
result.computeIfAbsent(factoryTypeName, key -> new ArrayList<>())
.add(factoryImplementationName.trim());
}
}
}
// Replace all lists with unmodifiable lists containing unique elements
result.replaceAll((factoryType, implementations) -> implementations.stream().distinct()
.collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList)));
cache.put(classLoader, result);
}
catch (IOException ex) {
throw new IllegalArgumentException("Unable to load factories from location [" +
FACTORIES_RESOURCE_LOCATION + "]", ex);
}
return result;
}
META-INF/spring.factories
去META-INF/spring.factories下面找资源
拿springboot的autoconfiguration看看,里面都是全类限定名
简单梳理
-
FACTORIES_RESOURCE_LOCATION的值是META-INF/spring.factories
-
Spring启动的时候会扫描所有jar路径下的META-INF/spring.factories,将其文件包装成Properties对象
-
从Properties对象获取到key值为EnableAutoConfiguration的数据,然后添加到容器里边。
3、@ComponentScan
@ComponentScan自动扫描包名下所有使用@Component、@Repository、@Service、@Controller注解的类,并注册为Bean。
常用方法
-
自定扫描路径下边带有@Controller,@Service,@Repository,@Component注解加入spring容器
-
通过includeFilters加入扫描路径下没有以上注解的类加入spring容器
-
通过excludeFilters过滤出不用加入spring容器的类
-
自定义增加了@Component注解的注解方式
4、自动配置
-
SpringBoot启动会加载大量的自动配置类
-
我们看我们需要的功能有没有在SpringBoot默认写好的自动配置类当中;
-
我们再来看这个自动配置类中到底配置了哪些组件;(只要我们要用的组件存在在其中,我们就不需要再手动配置了)
-
给容器中自动配置类添加组件的时候,会从properties类中获取某些属性。我们只需要在配置文件中指定这些属性的值即可;
xxxxAutoConfigurartion:自动配置类;给容器中添加组件
xxxxProperties:封装配置文件中相关属性;
4、总结
(1)、SpringApplication的实例化
SpringApplication做了四件事
-
推断应用的类型是普通的项目还是Web项目
-
查找并加载所有可用初始化器 , 设置到initializers属性中
-
找出所有的应用程序监听器,设置到listeners属性中
-
推断并设置main方法的定义类,找到运行的主类
(2)、run方法的执行
在SpringApplication实例初始化的时候,它会提前做几件事情:
-
根据classpath里面是否存在某个特征类(org.springframework.web.context.ConfigurableWebApplicationContext)来决定是否应该创建一个为Web应用使用的ApplicationContext类型。
-
使用SpringFactoriesLoader在应用的classpath中查找并加载所有可用的ApplicationContextInitializer。
-
使用SpringFactoriesLoader在应用的classpath中查找并加载所有可用的ApplicationListener。
-
推断并设置main方法的定义类。
它会执行以下步骤:
-
创建一个合适的ApplicationContext实例 (取决于classpath)。
-
注册一个CommandLinePropertySource,以便将命令行参数作为Spring properties。
-
刷新application context,加载所有单例beans。
-
激活所有CommandLineRunner beans。
四、yaml语法
1、基本规则
-
大小写敏感
-
使用缩进表示层级关系
-
禁止使用tab缩进,只能使用空格键
-
缩进长度没有限制,只要元素对齐就表示这些元素属于一个层级
-
使用#表示注释
-
字符串可以不用引号标注
2、YAML支持的数据结构
(1)、对象
使用冒号(:)表示键值对,同一缩进的所有键值对属于一个map,示例:
# YAML表示
age : 12
name : huang
(2)、数组
使用连字符(-)表示:
# YAML表示
- a
- b
- 12
(3)、纯量
单个的、不可再分的值
(4)、修改SpringBoot的默认端口号
传统xml配置:
<server>
<port>8081<port>
</server>
yaml配置:
server:
prot: 8080
3、注入配置文件
在springboot项目中的resources目录下新建一个文件 application.yml;编写一个实体类 Per'son;
public class Person {
private String name;
private Date birth;
private Map<String,Object> maps;
private List<Object> lists;
private Dog dog;
}
编写yaml配置
person:
name: qinjiang
age: 3
birth: 2000/01/01
maps: {k1: v1,k2: v2}
lists:
- code
- girl
- music
dog:
name: 旺财
age: 1
将配置文件中配置的每一个属性的值,映射到这个组件中;
/*
@ConfigurationProperties作用:将配置文件中配置的每一个属性的值,映射到这个组件中;
告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定参数 prefix = “person” :
将配置文件中的person下面的所有属性一一对应
*/
@Component
@ConfigurationProperties(prefix = "person")
public class Person {
private String name;
private Date birth;
private Map<String,Object> maps;
private List<Object> lists;
private Dog dog;
}
导入配置文件处理器,配置文件进行绑定就会有提示,需要重启
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>