【Spring Boot系列1】一文带你了解Spring Boot(上)

416 阅读9分钟

往期精选(欢迎转发~~)

主要带大家了解Spring Boost,让你对它有一个整体的认识。

前言

这几天一直没有更新,本来上一篇文章打算写MyBatis和实际项目的应用,当我把项目代码看完后,发现里面很多地方还是不太理解,就先不写了,等过两个月,实力水平提上来后,我再写这块内容。

这两天一直在看Spring Boost相关知识,其实它就是个框架,真要写些什么,其实不太好写,框架需要自己去多用。既然要写这个系列,那就还是从基础知识开始,这个系列不打算写很多篇,就掌握基本知识就可以,等后面在项目中使用,再结合具体场景再慢慢学习。

SpringBoot是什么?

随着动态语言的流行(Ruby、Groovy、Scala、Node.js),Java 的开发显得格外的笨重,繁多的配置、低下的开发效率、复杂的部署流程以及第三方技术集成难度大。

在上述环境下,Spring Boot 应运而生。它使用“习惯优于配置”(项目中存在大量的配置,此外还内置一个习惯性的配置,让你无须手动进行配置)的理念让你的项目快速运行起来。

使用 Spring Boot 很容易创建一个独立运行(运行 jar,内嵌 Servlet 容器)、准生产级别的基于 Spring 框架的项目,使用 Spring Boot 你可以不用或者只需要很少的 Spring 配置。

Spring Boot 核心功能

  1. 独立运行的 Spring 项目:Spring Boot 可以以 jar 包的形式独立运行,运行一个 Spring Boot 项目只需通过 java–jar xx.jar 来运行。
  2. 内嵌 Servlet 容器:Spring Boot 可选择内嵌 Tomcat、Jetty 或者 Undertow,这样我们无须以 war 包形式部署项目。
  3. 提供 starter 简化 Maven 配置:Spring 提供了一系列的 starter pom 来简化 Maven 的依赖加载,例如,当你使用了spring-boot-starter-web 时,会自动加入相关依赖包。
  4. 自动配置 Spring:Spring Boot 会根据在类路径中的 jar 包、类,为 jar 包里的类自动配置 Bean,这样会极大地减少我们要使用的配置。当然,Spring Boot 只是考虑了大多数的开发场景,并不是所有的场景,若在实际开发中我们需要自动配置 Bean,而 Spring Boot 没有提供支持,则可以自定义自动配置。
  5. 准生产的应用监控:Spring Boot 提供基于 http、ssh、telnet 对运行时的项目进行监控。
  6. 无代码生成和 xml 配置:Spring Boot 的神奇的不是借助于代码生成来实现的,而是通过条件注解来实现的,这是 Spring 4.x 提供的新特性。Spring 4.x 提倡使用 Java 配置和注解配置组合,而 Spring Boot 不需要任何 xml 配置即可实现 Spring 的所有配置。

Spring Boot的优缺点

优点:

  • 快速构建项目。
  • 对主流开发框架的无配置集成。
  • 项目可独立运行,无须外部依赖Servlet容器。
  • 提供运行时的应用监控。
  • 极大地提高了开发、部署效率。
  • 与云计算的天然集成。

缺点:

  • 版本迭代速度很快,一些模块改动很大。
  • 由于不用自己做配置,报错时很难定位。

@SpringBootApplication注解的三体结构解析

@SpringBootApplication

我们可以看到Spring Boot的启动类:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

@SpringBootApplication 是一个“三体”结构,实际上它是一个复合 Annotation:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Configuration
@EnableAutoConfiguration
@ComponentScanpublic
@interface
SpringBootApplication{...}

虽然它的定义使用了多个 Annotation 进行元信息标注,但实际上对于 SpringBoot 应用来说,重要的只有三个 Annotation,而“三体”结构实际上指的就是这三个 Annotation:

  • @Configuration
  • @EnableAutoConfiguration
  • @ComponentScan

所以,如果我们使用如下的 SpringBoot 启动类,整个 SpringBoot 应用依然可以与之前的启动类功能对等:

@Configuration
@EnableAutoConfiguration
@ComponentScan
class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

@Configuration

具体使用可以参考文章《【Spring基础系列3】Spring常用的注解》

很多 SpringBoot 的代码示例都喜欢在启动类上直接标注 @Configuration 或者 @SpringBootApplication,对于初接触 SpringBoot 的开发者来说,其实这种做法不便于理解,如果我们将上面的 SpringBoot 启动类拆分为两个独立的 Java 类,整个形势就明朗了:

@Configuration
@EnableAutoConfiguration
@ComponentScan
public class DemoConfiguration {
    @Bean
    public Controller controller() {
        return new Controller();
    }
}
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoConfiguration.class, args);
    }
}

所以,启动类 DemoApplication 其实就是一个标准的 Standalone 类型 Java 程序的 main 函数启动类,没有什么特殊的。而 @Configuration 标注的 DemoConfiguration 定义其实也是一个普通的 JavaConfig 形式的 IoC 容器配置类。

@EnableAutoConfiguration

@EnableAutoConfiguration 其实也没啥“创意”,简单概括一下就是,借助 @Import 的支持,收集和注册特定场景相关的 bean 定义:

  • @EnableScheduling 是通过 @Import 将 Spring 调度框架相关的 bean 定义都加载到 IoC 容器。
  • @EnableMBeanExport 是通过 @Import 将 JMX 相关的 bean 定义加载到 IoC 容器。

而 @EnableAutoConfiguration 也是借助 @Import 的帮助,将所有符合自动配置条件的 bean 定义加载到 IoC 容器,仅此而已!

其自身定义关键信息如下:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(EnableAutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {...}

其中,最关键的要属 @Import(EnableAutoConfigurationImportSelector.class),借助 EnableAutoConfigurationImportSelector,@EnableAutoConfiguration 可以帮助 SpringBoot 应用将所有符合条件的 @Configuration 配置都加载到当前 SpringBoot 创建并使用的 IoC 容器,就跟一只“八爪鱼”一样(如图 1 所示)。

借助于 Spring 框架原有的一个工具类:SpringFactoriesLoader 的支持,@EnableAutoConfiguration 可以“智能”地自动配置功效才得以大功告成!

@ComponentScan

具体使用可以参考文章《【Spring基础系列3】Spring常用的注解》

@ComponentScan是可有可无的,因为原则上来说,作为 Spring 框架里的“老一辈革命家”,@ComponentScan 的功能其实就是自动扫描并加载符合条件的组件或 bean 定义,最终将这些 bean 定义加载到容器中。加载 bean 定义到 Spring 的 IoC 容器,我们可以手工单个注册,不一定非要通过批量的自动扫描完成,所以说 @ComponentScan 是可有可无的。

如果我们当前应用没有任何 bean 定义需要通过 @ComponentScan 加载到当前 SpringBoot 应用对应使用的 IoC 容器,那么,除去 @ComponentScan 的声明,当前 SpringBoot 应用依然可以照常运行,功能对等。

SpringApplication.run执行流程

这个有点多,放到文章《【Spring Boot系列1】一文带你了解Spring Boot(下)》中进行讲解。

配置文件

在文章《【MyBatis系列4】MyBatis与Spring Boost整合》中,我们其实就用到了Spring Boost的配置,这里再详细讲述一下。

YAML vs XML

SpringBoot使用一个全局的配置文件,配置文件名是固定的(有两种形式):

  • application.properties
  • application.yml

配置文件的作用:修改SpringBoot自动配置的默认值;(SpringBoot在底层都给我们自动配置好了)

YAML:以数据为中心,比json、xml等更适合做配置文件。以前的配置文件;大多都使用的是 xxxx.xml文件。

XML例子:

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

YAML:配置例子

server:
  port: 8080

YAML基本使用姿势

先给个示例:

person:
	lastName: hello
	age: 18
	boss: false
	birth: 2017/12/12
	maps: {k1: v1,k2: 12}
	lists:
		 lisi
		 zhaoliu
	dog:
		name: 小狗
		age: 12

“lastName: hello”就是k:v格式,“maps: {k1: v1,k2: 12}”就是通过行表示的k:v格式,也可以写成:

maps: 
  k1: v1
  k2: 12

对于下面的lists,表示的是数组:

lists:
  ‐ lisi
  ‐ zhaoliu

也可以通过行表示为lists:[lisi,zhaoliu]。

配置文件注入的内容,后面会进行讲解。

后记

不想让篇幅太长,这篇就先介绍到这里,下一篇继续介绍Spring Boot的基础知识,主要讲述“SpringApplication.run执行流程”。

这两天看Spring Boot,感觉还是有些抽象,不像之前写的几个系列,看得见摸得着的东西比较多(就是自己可以动手去尝试),然后可以尝试的内容,感觉又稍微有点深,主要是目前用不着,也不想去花那个时间和精力,可能是自己刚接触这块的原因吧。

先不想那么多了, 把基础的知识先掌握了,后面再边学边看。