从零学习Springboot

579 阅读9分钟

1、简介

Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。通过这种方式,Spring Boot致力于在蓬勃发展的快速应用开发领域(rapid application development)成为领导者。

SpringBoot是由Pivotal团队在2013年开始研发、2014年4月发布第一个版本的全新开源的轻量级框架。它基于Spring4.0设计,不仅继承了Spring框架原有的优秀特性,而且还通过简化配置来进一步简化了Spring应用的整个搭建和开发过程。另外SpringBoot通过集成大量的框架使得依赖包的版本冲突,以及引用的不稳定性等问题得到了很好的解决。

1.1、SpringBoot所具备的特征:

  • (1)可以创建独立的Spring应用程序,并且基于其Maven或Gradle插件,可以创建可执行的JARs和WARs;
  • (2)内嵌Tomcat或Jetty等Servlet容器;
  • (3)提供自动配置的“starter”项目对象模型(POMS)以简化Maven配置;
  • (4)尽可能自动配置Spring容器;
  • (5)提供准备好的特性,如指标、健康检查和外部化配置;
  • (6)绝对没有代码生成,不需要XML配置。

1.2、springboot开启的两种方式:

1.2.1、继承spring-boot-starter-parent项目

<parent>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-parent</artifactId>
   <version>2.0.4.RELEASE</version>
</parent>

1.2.2、导入spring-boot-dependencies项目依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-dependencies</artifactId>
    <version>2.0.4.RELEASE</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>

1.3、Spring Boot 的核心注解:

@SpringBootApplication: Spring Boot的项目一般都会有*Application的入口类,入口类中会有main方法,这是一个标准的Java应用程序的入口方法。 @SpringBootApplication注解是Spring Boot的核心注解,它是一个组合注解:

@SpringBootConfiguration:这是Spring Boot项目的配置注解,这也是一个组合注解,与@Configuration作用相同,标识这是一个被装载的Bean,在Spring Boot项目中推荐使用@ SpringBootConfiguration替代@Configuration

@EnableAutoConfiguration:启用自动配置,该注解会使Spring Boot根据项目中依赖的jar包自动配置项目的配置项:如:我们添加了spring-boot-starter-web的依赖,项目中也就会引入SpringMVC的依赖,Spring Boot就会自动配置tomcat和SpringMVC

@ComponentScan:默认扫描@SpringBootApplication所在类的同级目录以及它的子目录,excludeFilters:指定不适合组件扫描的类型。

1.4、SpringBoot的核心配置文件有哪些?他们的区别是什么?都有什么格式?

SpringBoot的核心配置文件有application和bootstarp配置文件。

application文件主要用于Springboot自动化配置文件。 bootstarp文件主要有以下几种用途:

  • 使用Spring Cloud Config注册中心时 需要在bootStarp配置文件中添加链接到配置中心的配置属性来加载外部配置中心的配置信息。
  • 一些固定的不能被覆盖的属性。
  • 一些加密/解密的场景。

支持.properties.yml的格式, .yml采取的是缩进的格式 不支持@PeopertySource注解导入配置

1.5、修改启动图

可以根据自己需求玩一下,在下面网址输入自定义文字,然后生成

patorjk.com/software/ta…

点击 Test All有多种样式可以选择,复制生成的内容,在项目resourses目录下新建banner.txt,将内容复制进去,重启项目即可。

2、常见问题分析

2.1、Spring Boot 需要独立的容器运行吗?

springboot不需要独立的容器就可以运行,因为在springboot工程发布的jar文件里已经包含了tomcat的jar文件。springboot运行的时候,会创建tomcat对象,实现web服务功能。也可以将springboot发布成war文件,放到tomcat里运行。

2.2、Spring Boot 自动配置原理是什么?

Spring Boot的出现,得益于“习惯优于配置”的理念,没有繁琐的配置、难以集成的内容(大多数流行第三方技术都被集成),这是基于Spring 4.x提供的按条件配置Bean的能力。

开始使用Spring Boot时我们就知道,Spring Boot有一个全局配置文件:application.properties或application.yml。

最常配置的比如:server.port、logging.level.* 等等,然而我们实际用到的往往只是很少的一部分,这些属性都可以在官方文档中查找到: docs.spring.io/spring-boot…

自动配置的原理可以从启动类开始分析,Spring Boot的启动类上有一个@SpringBootApplication注解,这个注解是Spring Boot项目必不可少的注解。

进去之后我们看到有一个注解@EnableAutoConfiguration,这个就是完成自动配置的主角。

而这个注解也是一个派生注解,其中的关键功能由@Import提供,其导入的AutoConfigurationImportSelector的selectImports()方法通过SpringFactoriesLoader.loadFactoryNames()扫描所有具有META-INF/spring.factories的jar包。

@Import注解:

@Import注解就是之前xml配置中的import标签,可以用于依赖第三方包中bean的配置和加载
在4.2之前只支持导入配置类
在4.2,@Import注解支持导入普通的java类,并将其声明成一个bean

spring-boot-autoconfigure-x.x.x.x.jar里就有一个这样的spring.factories文件。

这个spring.factories文件也是一组一组的key=value的形式,其中一个key是EnableAutoConfiguration类的全类名,而它的value是一个xxxxAutoConfiguration的类名的列表,这些类名以逗号分隔,如下图所示:

这个@EnableAutoConfiguration注解通过@SpringBootApplication被间接的标记在了Spring Boot的启动类上。在SpringApplication.run(...)的内部就会执行selectImports()方法,找到所有JavaConfig自动配置类的全限定名对应的class,然后将所有自动配置类加载到Spring容器中。

但是这些自动配置类的并不是全部都加载的,需要满足某些条件才会生效。这些条件的限制在Spring Boot中以注解的形式体现,常见的条件注解有如下几项:

  • @ConditionalOnBean:当容器里有指定的bean的条件下。
  • @ConditionalOnMissingBean:当容器里不存在指定bean的条件下。
  • @ConditionalOnClass:当类路径下有指定类的条件下。
  • @ConditionalOnMissingClass:当类路径下不存在指定类的条件下。
  • @ConditionalOnProperty:指定的属性是否有指定的值,比如@ConditionalOnProperties(prefix=”xxx.xxx”, value=”enable”, matchIfMissing=true),代表当xxx.xxx为enable时条件的布尔值为true,如果没有设置的情况下也为true。

找个例子进一步研究一下,以`server.port=80 `为例,加载这个配置的是ServletWebServerFactoryAutoConfiguration,

在ServletWebServerFactoryAutoConfiguration类上,有一个@EnableConfigurationProperties注解:开启配置属性,而它后面的参数是一个ServerProperties类真正加载配置的就是这个类。

@EnableConfigurationProperties:负责导入这个已经绑定了属性的bean到spring容器中

如果一个配置类只配置@ConfigurationProperties注解,而没有使用@Component,那么在IOC容器中是获取不到properties
配置文件转化的bean。说白了 @EnableConfigurationProperties 相当于把使用 @ConfigurationProperties 的类进行了一次注入

ServerProperties的具体内容:

@ConfigurationProperties,它的作用就是从配置文件中绑定属性到对应的bean上,也就是说,真正“限制”我们可以在全局配置文件中配置哪些属性的类就是这些XxxxProperties类,它与配置文件中定义的prefix关键字开头的一组属性是一一对应的。

至此,我们大致可以了解。在全局配置的属性如:server.port等,通过@ConfigurationProperties注解,绑定到对应的XxxxProperties配置实体类上封装为一个bean,然后再通过@EnableConfigurationProperties注解导入到Spring容器中。

而诸多的XxxxAutoConfiguration自动配置类,就是Spring容器的JavaConfig形式,作用就是为Spring 容器导入bean,而所有导入的bean所需要的属性都通过xxxxProperties的bean来获得

所以这个问题的答案如下:

Spring Boot启动的时候会通过@EnableAutoConfiguration注解找到META-INF/spring.factories配置文件中的所有自动配置类,并对其进行加载,而这些自动配置类都是以AutoConfiguration结尾来命名的,它实际上就是一个JavaConfig形式的Spring容器配置类,它能通过以Properties结尾命名的类中取得在全局配置文件中配置的属性如:server.port,而XxxxProperties类是通过@ConfigurationProperties注解与全局配置文件中对应的属性进行绑定的。

参考:blog.csdn.net/u014745069/…

2.3、如何理解 Spring Boot 中的 Starters?

Starters可以理解为启动器,它包含了一系列可以集成到应用里面的依赖包,你可以一站式集成Spring及其他技术,而不需要到处找示例代码和依赖包。如你想使用Spring JPA访问数据库,只要加入spring-boot-starter-data-jpa启动器依赖就能使用了。 Starters包含了许多项目中需要用到的依赖,它们能快速持续的运行,都是一系列得到支持的管理传递性依赖。

2.4、如何在 Spring Boot 启动的时候运行一些特定的代码?

可以实现接口 ApplicationRunner 或者 CommandLineRunner,这两个接口实现方式一样,它们都只提供了一个 run 方法。

实现ApplicationRunner:

public class TestRun implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        System.out.println("启动器启动");
    }
}

实现CommandLineRunner:

public class TestRun implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println("启动器启动");
    }
}

2.5、Spring Boot 有哪几种读取配置的方式?

Spring Boot 可以通过 @PropertySource,@Value,@Environment, @ConfigurationProperties 来绑定变量

在application.yml或者properties文件中添加:

test:
  name: Tom

我这里使用的junit,所以`@PropertySource`变成了`@TestPropertySource`。

2.5.1、读取application文件

@Value注解读取方式

@RunWith(value = SpringJUnit4ClassRunner.class) //在使用所有注释前必须使用@RunWith(SpringJUnit4ClassRunner.class),让测试运行于spring测试环境
@SpringBootTest
public class Test1 {

    @Value(value = "${test.name}")
    private String name;


    @Test
    public void test(){
        System.out.println("name:"+name);

    }

}

@ConfigurationProperties注解读取方式

@RunWith(value = SpringJUnit4ClassRunner.class) //在使用所有注释前必须使用@RunWith(SpringJUnit4ClassRunner.class),让测试运行于spring测试环境
@SpringBootTest
@Component
@ConfigurationProperties(prefix = "test")
public class Test1 {

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Test
    public void test(){
        System.out.println("name:"+name);

    }

}

2.5.2、读取指定文件

注意:@PropertySource不支持yml文件读取。

资源目录下建立test.properties:

test.name=Jerry

@PropertySource+@Value注解读取方式

@RunWith(value = SpringJUnit4ClassRunner.class) //在使用所有注释前必须使用@RunWith(SpringJUnit4ClassRunner.class),让测试运行于spring测试环境
@TestPropertySource("classpath:test.properties")//用来指定加载的Spring配置文件的位置,会加载默认配置文件
@SpringBootTest
public class Test1 {

    @Value("${test.name}")
    private String name;


    @Test
    public void test(){
        System.out.println("name:"+name);

    }

}

@PropertySource+@ConfigurationProperties注解读取方式

@RunWith(value = SpringJUnit4ClassRunner.class) //在使用所有注释前必须使用@RunWith(SpringJUnit4ClassRunner.class),让测试运行于spring测试环境
@TestPropertySource("classpath:test.properties")//用来指定加载的Spring配置文件的位置,会加载默认配置文件
@SpringBootTest
@Component
@ConfigurationProperties(prefix = "test")
public class Test1 {

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Test
    public void test(){
        System.out.println("name:"+name);

    }

}

2.6、Spring Boot 如何定义多套不同环境配置?

2.6.1、基于properties文件类型

applcation.properties

application-dev.properties

application-test.properties

application-prod.properties

假设有现在四个配置文件,然后在applcation.properties文件中指定当前的环境spring.profiles.active=test,这时候读取的就是application-test.properties文件。

2.6.2、基于yml文件类型


spring:
 profiles:
   active: test
 
---
spring:
 profiles: dev  
 
server:
 port: 8080  
 
---
spring:
 profiles: test  
 
server:
 port: 8081    
 
---
spring
 profiles: prod

server:
 port: 8082  


指定active属性的值,此时读取的就是test的配置。

持续更新中。。。