Spirng Boot简介
什么是Spring Boot? 我们看看Spring Boot(https://spring.io/projects/spring-boot)的自我介绍:
Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can "just run".
Spring Boot用创建独立的, 生产级的, 可以独立运行的基于Spring的应用程序。Spring Boot是一个(为简化Spring应用程序开发的)开源框架, 是对Spring的再封装, Spring能做的事, Spring Boot都可以。 Spring Boot通过启动器(starter)的方式,提供了第三方库的自动配置和整合, 做到了开箱即用, 可以让开发者能够更加专注于业务逻辑。
Spring Boot的特性:
- Create stand-alone Spring applications
- Embed Tomcat, Jetty or Undertow directly (no need to deploy WAR files)
- Provide opinionated 'starter' dependencies to simplify your build configuration
- Automatically configure Spring and 3rd party libraries whenever possible
- Provide production-ready features such as metrics, health checks, and externalized configuration
- Absolutely no code generation and no requirement for XML configuration
Spring Boot内嵌了Web容器(Tomcat, Jetty和Undertow), 使得我们可以创建独立运行的Sping Web应用程序, 不需要打包成WAR文件并部署。Spring Boot提供了大量的"starter(启动器)", 一个"starter"可以看成是一个独立的功能模块, starter包含了实现特定功能的(特定第三方库)的自动配置支持(***AutoConfiguration类)。Spring Boot还提供了生产环境方面的增强(主要集中在监控和管理方面), 如: 指标收集, 健康检查, 外部配置。
Spring Boot Reference Documentation(https://docs.spring.io/spring-boot/docs/2.6.4/reference/html/index.html),是我主要参考的官方文档,以pdf版本为例,文档的结构:
- 第1~6章节主要介绍Spring Boot和其运行环境方面的基本信息,是入门(Getting Started)的主要参考;
- 第7章介绍的是Spring Boot的通用(核心)功能的用法;
- 第8~11章节介绍的是Spring Boot的主要功能模块(starter)的用法;
- 第17章节介绍的是"How-to", 介绍了开发过程中常用遇到的问题以及解答;
- 附录(Appendices)章节, 包含常用附录信息,如: "Appendix A: Common Application Properties"包含Spring Boot的外部配置文件参数列表;
创建一个Spring Boot项目
Spring Boot提供了一系列的工具和插件来简化Spring Boot项目的创建。
Spring Initializr
Spring Initializr是官方提供的Spring Boot项目创建工具,可以快速生成spring boot项目。Spring Initializr提供了Web UI和Web Service两种方式,Web UI的页面地址为: https://start.spring.io/ ,Web Service主要给一些插件程序使用的,如下面将要介绍的Eclipse插件’Spring Tools’。
Spring Initializr是开源的,可以通过https://github.com/spring-io/start.spring.io获取。我们可以通过源代码建自己的Spring Initializr实例,这对于无法访问的互联网的场景非常有用。
使用浏览器访问 https://start.spring.io/ 来到了Spring Initializr页面:
下载并解压Spring Initializr生成的项目文件, 并在Eclipse中引入该项目:主菜单"File" -> “Import…”, 弹出向导对话框选"Maven" -> “Existing Maven Projects”。
耐心等待Maven下载依赖的库文件后即可以开始进行后续开发。
Spring Tools/Spring Tool Suite
对于Eclipse开发环境,Spring也提供了相关的插件,Spring Tools(又叫Spring Tool Suite),我们可以通过Eclipse Marketplace下载安装:
需要注意的是: Spring Tools默认调用的是https://start.spring.io提供的Web服务,也是需要互联网访问的。安装好Spring Tools后,走菜单"File" -> “Project…”, 在弹出向导对话框中选"Spring Boot" -> “Spring Starter Poject”。
Spring Boot项目基本结构
Spring Initializr极大的简化了项目的创建和配置,Spring Initializr会根据我们的来创建pom.xml文件和目录结构。
pom.xml包含了我们在创建时候选择的依赖(starter), 其中的spring-boot-starter是spring boot的基础,是每个Spring Boot项目必须包含的。
对于已经创建好的项目,如果我们还需要添加依赖(或者漏选了),除了手动添加,一个更好的做法是通过开发工具的Spring插件来添加,以Eclipse+Spring Tools为例,选择我们的项目,右键菜单选择"Sping" -> “Add Starters”
Spring Initializr还为我们的项目自动创建了一个java文件:
package org.littlestar.learning3;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Learning3Application {
public static void main(String[] args) {
SpringApplication.run(Learning3Application.class, args);
}
}
这是一个经典的SpringBoot启动类,包含一个@SpringBootApplication注解和Java的主函数(main),可以像普通java应用程序一样直接运行SpringBoot应用程序,特别是Web类型的Spring Boot程序。
@SpringBootApplication注解是Spring Boot引入的新注解,但没什么神奇的功能,查看源码和他的JavaDoc描述可知,@SpringBootApplication用于标识Spring配置类, 是@Configuration, @EnableAutoConfiguration and @ComponentScan注解的组合。@SpringBootApplication注解不是必须的,如果你不需要自动装配和扫描,用@Configuration注解即可,@SpringBootApplication注解也不一定非要标注在启动类上,我们要的是把配置类作为参数传递给SpringApplication,让SpringApplication根据我们提供的配置类来初始化Spring容器,SpringApplication类才是引导和启动Sping应用程序启动的核心。如果你要分析Spring Boot的源代码和自动配置机制,SpringApplication是一个非常好的切入点。
Java主函数代码只有一行,调用SpringApplication.run()静态方法。查看源代码:
//SpringApplication源代码...
public class SpringApplication {
...
public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
// 将Spring配置类做为参数创建SpringApplication实例; 调用run方法返回配置完成后的Spring容器;
return new SpringApplication(primarySources).run(args);
}
...
}
这其实是一个简化的写法, 启动Spring Boot程序启动的步骤是,将我们编写的配置类作为参数,创建(new)一个SpringApplication的实例,然后调用实例的run方法启动程序,并返回Spring容器。SpringApplication详细介绍和用法参考"Chapter 7. Core Features"章节。
在项目的src/main/resources源代码目录下还包含了一个"application.properties"空文件,该文件是Spring Boot的外部配置文件, 用来配置Spring Boot和Starter,如设置日志级别。查看项目"Java Build Path"属性可知,src/main/resources的会输出到target/classes目录, 也就说Spring Boot会程序的在classpath下查找这个文件。Spring Boot还支持YAML格式的配置(application.yml),跟多关于配置文件信息,可以参考"7.2. Externalized Configuration"和"Appendix A: Common Application Properties"。
编写Spring Boot程序
任何相遇都是以hello开始, bye-bye结束,咱也不能免俗,先来个简单的hello word作为开始, 为了简单在创建过程中我们什么模块也不选。回顾一下之前的学习,开发一个Spring程序,我们首先要编写相关的业务逻辑的类(如之前的BankingService, Spring MVC的Controller), 然后通过配置让Spring容器来装载这些Bean Spring Boot也是类似的:
假设我们有两个模块HelloJava.java和HelloSpring.java:
HelloJava .java和配置类Package1Config.java放在package1包下;
HelloSpring.java和配置类为Package2Config.java放在package2包下;
最后编写一个App1.java启动应用程序。
HelloJava .java
package org.littlestar.learning3.package1;
public class HelloJava {
public String hello() {return "Hello Java";}
}
Package1Config.java
package org.littlestar.learning3.package1;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
public class Package1Config {
@Bean
public HelloJava helloJava() {
HelloJava hello = new HelloJava();
return hello;
}
}
HelloSpring.java
package org.littlestar.learning3.package2;
public class HelloSpring {
public String hello() {return "Hello Spring";}
}
Package2Config.java
package org.littlestar.learning3.package2;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
public class Package2Config {
@Bean
public HelloSpring helloSpring() {
HelloSpring hello = new HelloSpring();
return hello;
}
}
App1.java
package org.littlestar.learning3;
import org.littlestar.learning3.package1.HelloJava;
import org.littlestar.learning3.package1.Package1Config;
import org.littlestar.learning3.package2.HelloSpring;
import org.littlestar.learning3.package2.Package2Config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.context.ConfigurableApplicationContext;
public class App1 {
final static Logger LOGGER = LoggerFactory.getLogger(App1.class);
public static void main(String[] args) {
SpringApplication springApplication = new SpringApplication(Package1Config.class, Package2Config.class);
// springApplication.setXxxx(); //这里设置Spring boot应用程序的启动选项
ConfigurableApplicationContext context = springApplication.run(args);
// 列出Spring Boot自动装载的所有Beans的名字
String[] allBeanNames = context.getBeanDefinitionNames();
for (String beanName : allBeanNames) {
LOGGER.info(beanName);
}
// 通过Spring容器使用我们定义的Beans, 如果App1也是一个Bean,还可以使用@Autowired
HelloJava helloJava = context.getBean("helloJava", HelloJava.class);
HelloSpring helloSpring = context.getBean("helloSpring", HelloSpring.class);
LOGGER.info(helloJava.hello());
LOGGER.info(helloSpring.hello());
}
}
这里看起来跟前面Spring的写法没什么优势,但如果使用@Bean注解标注HelloJava和HelloSpring类,并且将他们放在启动类App1所在的包或者其下的子包内,App1使用@SpringBootApplication进行标注,那么就不需要Package1Config和Package2Config这两个配置类,整个程序看起来精简了许多,这引出了Spring Boot的一个重要的思想,就是"约定优于配置"。