SpringBoot学习笔记

117 阅读3分钟

SpringBoot

什么是Spring Boot

Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。用我的话来理解,就是spring boot其实不是什么新的框架,它默认配置了很多框架的使用方式,就像maven整合了所有的jar包,spring boot整合了所有的框架

更多介绍见链接:Springboot介绍(超详细)_岭师小白的博客-CSDN博客_springboot详细介绍

创建Spring Boot项目

可以从官网download 压缩包,也可以从idea中直接套用官网模板创建

注意:项目结构如controller包、service包、dao包、pojo包都要在启动函数主入口同级目录下创建

在resources目录下新建banner.txt可以改变启动图标

原理初探

自动配置:

pom.xml

  • spring-boot-dependencies:核心依赖在父工程中
  • 在引入springboot依赖时不需要指定版本就是因为在上条中有许多版本仓库

启动器:

  • <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    
  • 启动器:其实就是springboot的启动场景;
  • 如spring-boot-starter-web,就会自动导入web环境的所有依赖
  • springboot会将所有的功能场景变成一个个的启动器
  • 要使用什么功能只需要导入对应的启动器starter 从spring官网找

主程序:

@SpringBootApplication
public class SpringbootDemoApplication {

    public static void main(String[] args) {
        //将springboot应用启动
        SpringApplication.run(SpringbootDemoApplication.class, args);
    }

}
  • 注解:

    • @SpringBootConfiguration:springboot的配置
          @Configuration:spring配置类
              @Component:表示这也是一个是spring的组件
      @EnableAutoConfiguration:自动导入配置
          @AutoConfigurationPackage:自动配置包
              @Import({Registrar.class}):自动配置包注册
          @Import({AutoConfigurationImportSelector.class}):自动配置导入选择
      

      List configurations = this.getCandidateConfigurations(annotationMetadata, attributes);

      获取候选配置
      
      ```java
      protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
              List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.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;
          }
      

      META-INF/spring.factories. 自动配置的核心文件,位于依赖仓库的spring-boot-autoconfigure包下 f63c3f053b715ec47f83aabb7ec574eb8d2826cc.png

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");
                LinkedMultiValueMap result = new LinkedMultiValueMap();

                while(urls.hasMoreElements()) {
                    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);
            }
        }
    }

自动装配原理导图

结论:springboot所有的自动配置都是在启动的时候扫描并加载:spring.factories所有的自动配置类都在这里,但并不是所有的都生效。要判断条件是否成立,只要在pom文件中导入对应的starter,就有对应的启动器,之后自动装配就能生效。

  1. springboot在启动时,从类路径下META-INF/spring.factories获取指定的值
  2. 将这些自动配置的类导入容器,自动配置类才能生效
  3. 整个JavaEE,解决自动配置的东西都在spring-boot-autoconfigure包下
  4. 它会把所有需要导入的组件,以类名的方式返回,这些组件就会被添加到容器
  5. 容器中也会存在非常多的XXXAutoConfiguration的文件,正是这些类给容器中导入了这个场景中所需要的所有组件
  6. 在有自动配置类之后免去了手动编写配置文件的工作

Run

其实运行的是一整个服务

@SpringBootApplication
public class SpringbootDemoApplication {

    public static void main(String[] args) {
        //将springboot应用启动
        //SpringApplication类
        //run方法
        SpringApplication.run(SpringbootDemoApplication.class, args);
    }

}
Application类

这个类主要做了以下事情

  1. 推断应用的类型是普通项目还是web项目
  2. 查找并加载所有可用初始化器,设置到initializers属性中
  3. 找出所有的应用程序监听器,设置到listener属性中
  4. 推断并设置main方法的定义类,找到运行的主类

关于SpringBoot的理解:

  • 自动装配
  • run()方法

配置文件

SpringBoot采用全局配置文件,配置文件的名称是固定的

  • application.properties

    • 语法结构:key = value
  • application.yaml

    • 语法结构:key 空格 value

配置文件的作用: 修改SpringBoot自动配置的默认值

yaml

标记语言

以前的配置文件,大多数使用xml来配置,yaml相较于xml更加简洁

yaml配置:

# 普通kv键值对
server:
    port: 8080
# 对象
student:
    name: xuan
    age: 5
# 对象行内写法
student: {name: xuan, age: 5}
# 数组
pets:
    - cat
    - dog
pets: [cat,dog]
# 对空格的要求十分严格
# 可以注入到配置类中

xml配置:

<server>
    <port>8080</port>
</server>

properties配置:

# properties只能保存键值对
name=xuan
student.name=xuan
student.age=5

yaml基础语法

说明:语法要求严格!

1、空格不能省略

2、以缩进来控制层级关系,只要是左边对齐的一列数据都是同一个层级的。

3、属性和值的大小写都是十分敏感的。

字面量:普通的值  [ 数字,布尔值,字符串  ]

字面量直接写在后面就可以 , 字符串默认不用加上双引号或者单引号;

k: v

注意:

  • “ ” 双引号,不会转义字符串里面的特殊字符 , 特殊字符会作为本身想表示的意思;

    比如 :name: "kuang \n shen"   输出 :kuang  换行   shen

  • '' 单引号,会转义特殊字符 , 特殊字符最终会变成和普通字符一样输出

    比如 :name: ‘kuang \n shen’   输出 :kuang  \n   shen