主要带大家了解Spring Boost,让你对它有一个整体的认识。
前言
这几天一直没有更新,本来上一篇文章打算写MyBatis和实际项目的应用,当我把项目代码看完后,发现里面很多地方还是不太理解,就先不写了,等过两个月,实力水平提上来后,我再写这块内容。
这两天一直在看Spring Boost相关知识,其实它就是个框架,真要写些什么,其实不太好写,框架需要自己去多用。既然要写这个系列,那就还是从基础知识开始,这个系列不打算写很多篇,就掌握基本知识就可以,等后面在项目中使用,再结合具体场景再慢慢学习。
SpringBoot是什么?
随着动态语言的流行(Ruby、Groovy、Scala、Node.js),Java 的开发显得格外的笨重,繁多的配置、低下的开发效率、复杂的部署流程以及第三方技术集成难度大。
在上述环境下,Spring Boot 应运而生。它使用“习惯优于配置”(项目中存在大量的配置,此外还内置一个习惯性的配置,让你无须手动进行配置)的理念让你的项目快速运行起来。
使用 Spring Boot 很容易创建一个独立运行(运行 jar,内嵌 Servlet 容器)、准生产级别的基于 Spring 框架的项目,使用 Spring Boot 你可以不用或者只需要很少的 Spring 配置。
Spring Boot 核心功能
- 独立运行的 Spring 项目:Spring Boot 可以以 jar 包的形式独立运行,运行一个 Spring Boot 项目只需通过 java–jar xx.jar 来运行。
- 内嵌 Servlet 容器:Spring Boot 可选择内嵌 Tomcat、Jetty 或者 Undertow,这样我们无须以 war 包形式部署项目。
- 提供 starter 简化 Maven 配置:Spring 提供了一系列的 starter pom 来简化 Maven 的依赖加载,例如,当你使用了spring-boot-starter-web 时,会自动加入相关依赖包。
- 自动配置 Spring:Spring Boot 会根据在类路径中的 jar 包、类,为 jar 包里的类自动配置 Bean,这样会极大地减少我们要使用的配置。当然,Spring Boot 只是考虑了大多数的开发场景,并不是所有的场景,若在实际开发中我们需要自动配置 Bean,而 Spring Boot 没有提供支持,则可以自定义自动配置。
- 准生产的应用监控:Spring Boot 提供基于 http、ssh、telnet 对运行时的项目进行监控。
- 无代码生成和 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,感觉还是有些抽象,不像之前写的几个系列,看得见摸得着的东西比较多(就是自己可以动手去尝试),然后可以尝试的内容,感觉又稍微有点深,主要是目前用不着,也不想去花那个时间和精力,可能是自己刚接触这块的原因吧。
先不想那么多了, 把基础的知识先掌握了,后面再边学边看。