SpringBoot(一)

一、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自动装配原理——Java3y

SpringBoot自动装配原理——狂神

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做了四件事

  1. 推断应用的类型是普通的项目还是Web项目

  2. 查找并加载所有可用初始化器 , 设置到initializers属性中

  3. 找出所有的应用程序监听器,设置到listeners属性中

  4. 推断并设置main方法的定义类,找到运行的主类

(2)、run方法的执行

在SpringApplication实例初始化的时候,它会提前做几件事情:

  1. 根据classpath里面是否存在某个特征类(org.springframework.web.context.ConfigurableWebApplicationContext)来决定是否应该创建一个为Web应用使用的ApplicationContext类型。

  2. 使用SpringFactoriesLoader在应用的classpath中查找并加载所有可用的ApplicationContextInitializer。

  3. 使用SpringFactoriesLoader在应用的classpath中查找并加载所有可用的ApplicationListener。

  4. 推断并设置main方法的定义类。

它会执行以下步骤:

  1. 创建一个合适的ApplicationContext实例 (取决于classpath)。

  2. 注册一个CommandLinePropertySource,以便将命令行参数作为Spring properties。

  3. 刷新application context,加载所有单例beans。

  4. 激活所有CommandLineRunner beans。

四、yaml语法

yaml语法

1、基本规则

  1. 大小写敏感

  2. 使用缩进表示层级关系

  3. 禁止使用tab缩进,只能使用空格键

  4. 缩进长度没有限制,只要元素对齐就表示这些元素属于一个层级

  5. 使用#表示注释

  6. 字符串可以不用引号标注

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>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DF10F-0001A

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值