概述 在脚本语言和敏捷开发流行的当前,Java 开发显得很笨重,即便是在传统的 J2EE 开发中引入了 Spring,整合和配置的繁琐还是一直饱受诟病,为了解决这个问题,Spring Boot 应运而生。Spring Boot 并没有创造新的技术,它基于“习惯优于配置”,即内部有一套默认的配置,使你无需手动配置便可使用 Spring 平台的产品。  
 
Spring Boot 有很多重要的特性,这里简单列举几个具有代表性的:
独立运行  可以以 jar 包的形式独立运行,使用命令 java -jar xxx.jar。 
内置 Servlet 容器  内置 Servlet 容器,同时有多种容器可以选择,这样就无需部署 war 包。 
自动配置  考虑了大多数开发场景,为项目 jar 包中的类自动配置 Bean 并纳入容器,同时支持自定义的配置。 
无 xml 配置,无代码生成  如果只是代替我们将代码生成,Spring Boot 也就没有这么神奇了。Spring Boot 使用条件注解,同时可以通过 Java 类配置和注解结合,避免使用 xml。 
 
快速开始 如果使用 eclipse 等 IDE 可以安装 Spring Tool Suite  插件,这里使用 IDEA 作为 IDE。
首先第一步是创建一个新项目,填写项目相关信息。
 		 		 		 		 接下来需要选择项目的依赖,比如 Web 开发可能需要 Web 模块、Spring Data JPA 模块等。 		 		 		 最后耐心等待。IDEA 会自动执行新建项目的操作(包括下载依赖包、索引项目文件等),新建好的项目结构如下图。	 		 		
		
pom.xml 分析 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 <?xml version="1.0"  encoding="UTF-8" ?> <project  xmlns ="http://maven.apache.org/POM/4.0.0"           xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"           xsi:schemaLocation ="http://maven.apache.org/POM/4.0.0           http://maven.apache.org/xsd/maven-4.0.0.xsd" >    <modelVersion > 4.0.0</modelVersion >      <parent >          <groupId > org.springframework.boot</groupId >          <artifactId > spring-boot-starter-parent</artifactId >          <version > 1.5.20.RELEASE</version >          <relativePath />       </parent >      <groupId > com.nekolr</groupId >      <artifactId > demo</artifactId >      <version > 0.0.1-SNAPSHOT</version >      <name > demo</name >      <description > Demo project for Spring Boot</description >      <properties >          <java.version > 1.8</java.version >      </properties >      <dependencies >          <dependency >              <groupId > org.springframework.boot</groupId >              <artifactId > spring-boot-starter-web</artifactId >          </dependency >          <dependency >              <groupId > org.springframework.boot</groupId >              <artifactId > spring-boot-starter-test</artifactId >              <scope > test</scope >          </dependency >      </dependencies >      <build >          <plugins >              <plugin >                  <groupId > org.springframework.boot</groupId >                  <artifactId > spring-boot-maven-plugin</artifactId >              </plugin >          </plugins >      </build >  </project > 
 
分析 pom.xml,其中有一个父级依赖:spring-boot-starter-parent,它的父级依赖 spring-boot-dependencies 里定义了常用的 jar 包和版本,免去了配置依赖 jar 包。dependencies 中定义了 web 和 test 的 starter,这样就添加了 web 开发依赖和测试依赖。 spring-boot-maven-plugin 是 Spring Boot 的编译插件,用来将项目打包成一个可运行的 jar。  
入口类分析 创建完成的 Spring Boot 项目通常会有一个名为 *Application 的入口类,入口类有个 Java 标准的 main 方法,在 main 方法中运行如 SpringApplication.run(DemoApplication.class, args) 的代码来启动项目。  
入口类一般带有 @SpringBootApplication 注解,查看注解源:  
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @SpringBootConfiguration @EnableAutoConfiguration @ComponentScan(     excludeFilters = {@Filter(     type = FilterType.CUSTOM,     classes = {TypeExcludeFilter.class} ), @Filter(     type = FilterType.CUSTOM,     classes = {AutoConfigurationExcludeFilter.class} )} ) public  @interface  SpringBootApplication {    @AliasFor(          annotation = EnableAutoConfiguration.class,         attribute = "exclude"     )     Class<?>[] exclude() default  {};     @AliasFor(          annotation = EnableAutoConfiguration.class,         attribute = "excludeName"     )     String[] excludeName() default  {};     @AliasFor(          annotation = ComponentScan.class,         attribute = "basePackages"     )     String[] scanBasePackages() default  {};     @AliasFor(          annotation = ComponentScan.class,         attribute = "basePackageClasses"     )     Class<?>[] scanBasePackageClasses() default  {}; } 
 
@SpringBootApplication 是一个组合注解,它包含 @SpringBootConfiguration、@EnableAutoConfiguration 和 @ComponentScan 注解。 		 其中,@EnableAutoConfiguration 可以让 Spring Boot 根据类路径中依赖的 jar 包为项目自动配置。比如添加了 spring-boot-starter-web 依赖,则会自动添加 tomcat 和 Spring MVC 依赖,同时自动配置 tomcat 和 Spring MVC。  
使用 exclude 可以在扫描时过滤某些类,如 @SpringBootApplication(exclude=CacheAutoConfiguration.class)。Spring Boot 会自动扫描 @SpringBootApplication 所在类同级或下级包中的 Bean,因此入口类最好放在 groupId.artifactId 包下。
Banner 在 src/main/resources 下添加 banner.txt 文件,在 http://patorjk.com/software/taag  中选择 banner 样式并复制到 banner.txt 文件中。当然可以选择不显示 banner。  
1 2 3 4 5 6 7 8 9 @SpringBootApplication public  class  DemoApplication  {	public  static  void  main (String[] args)  { 		SpringApplication  app  =  new  SpringApplication (DemoApplication.class); 		app.setBannerMode(Banner.Mode.OFF); 		app.run(args); 	} } 
 
1 2 3 4 5 6 7 8 9 @SpringBootApplication public  class  DemoApplication  {    public  static  void  main (String[] args)  {         new  SpringApplicationBuilder (DemoApplication.class)                 .bannerMode(Banner.Mode.OFF)                 .run(args);     } } 
 
配置 POM 如果不想使用默认的 jar 版本,可以在 pom.xml 中使用 properties 添加版本以覆盖默认的版本。  
1 2 3 <properties >     <lombok.version > 1.16.18</lombok.version >  </properties > 
 
默认的 spring-boot-starter-parent 不一定适合所有的场景,可以使用自定义的父级依赖。如果不想使用默认的 spring-boot-starter-parent,又想使用默认的依赖管理,可以使用 import,并在 pom.xml 中如下配置:  
1 2 3 4 5 6 7 8 9 10 11 12 <dependencyManagement >     <dependencies >          <dependency >                           <groupId > org.springframework.boot</groupId >              <artifactId > spring-boot-dependencies</artifactId >              <version > 1.5.20.RELEASE</version >              <type > pom</type >              <scope > import</scope >          </dependency >      </dependencies >  </dependencyManagement > 
 
上述配置不能通过 properties 修改默认的依赖版本,只能在 dependencyManagement 中指定版本。  
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <dependencyManagement >     <dependencies >          <dependency >                           <groupId > org.springframework.boot</groupId >              <artifactId > spring-boot-dependencies</artifactId >              <version > 1.5.20.RELEASE</version >              <type > pom</type >              <scope > import</scope >          </dependency >          <dependency >              <groupId > org.projectlombok</groupId >              <artifactId > lombok</artifactId >              <version > 1.16.18</version >          </dependency >      </dependencies >  </dependencyManagement > 
 
Srping Boot 提供了很多起始依赖(starter pom),具体参考:spring boot starter pom 。同时可以选择不同的 Servlet 容器,如 spring-boot-starter-jetty 和 spring-boot-starter-undertow。  
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <dependencies >     <dependency >          <groupId > org.springframework.boot</groupId >          <artifactId > spring-boot-starter-web</artifactId >                   <exclusions >              <exclusion >                  <groupId > org.springframework.boot</groupId >                  <artifactId > spring-boot-starter-tomcat</artifactId >              </exclusion >          </exclusions >      </dependency >           <dependency >          <groupId > org.springframework.boot</groupId >          <artifactId > spring-boot-starter-jetty</artifactId >      </dependency >  </dependencies > 
 
spring-boot-devtools 是为开发者提供的一个热部署工具,当我们修改了项目 classpath 下的文件时,Spring Boot 会重启应用,当然这个启动很快。原理就是使用了两个类加载器,一个为 base 类加载器,用来加载一般不会改变的类,如第三方 jar 包等;一个为 restart 类加载器,用来加载经常改变的类,如我们正在开发的类,应用重启时,原先的 restart 加载器被丢弃,重新创建 restart 加载器加载修改过的文件。		 		 如果觉得 restart 不够快,还可以尝试使用 JRebel   或 Spring Loaded  。  
1 2 3 4 5 6 7 <dependency >     <groupId > org.springframework.boot</groupId >      <artifactId > spring-boot-devtools</artifactId >           <optional > true</optional >  </dependency > 
 
触发重启 只要 classpath 中的文件发生改变就会触发。在使用 IDE 时,如果是 eclipse,只需编辑后保存即可(eclipse 默认开启了 build automatically)。如果是 IDEA,一般情况下可能没有设置自动 build,此时需要手动 build 项目。  
当然,某些文件的改变并不会重启应用,而是重新加载资源。查看 DevToolsProperties 类的源码会发现,默认不重启应用的目录和文件为:  
META-INF/maven/** 
META-INF/resources/** 
resources/** 
static/** 
public/** 
templates/** 
**/*Test.class 
**/*Tests.class 
git.properties 
META-INF/build-info.properties 
 
(其中 static、public、templates 都是 resources 下目录)。可以在全局配置文件中选择排除某些目录:  
1 2 spring.devtools.restart.exclude =static/**,public/** 
 
如果想保留默认配置并添加额外的排除配置,可以使用 spring.devtools.restart.additional-exclude。对于不在 classpath 下的文件,也可以使用 spring.devtools.restart.additional-paths 设置目录以监视其更改。
关闭热部署 1 2 spring.devtools.restart.enabled =false 
 
1 2 3 4 5 6 7 public  static  void  main (String[] args)  {       System.setProperty("spring.devtools.restart.enabled" , "false" );     new  SpringApplicationBuilder (DemoApplication.class)             .bannerMode(Banner.Mode.OFF)             .run(args); } 
 
设置触发文件 有的时候我们会频繁修改某些文件,我们希望能够在某个时机来重启。通过设置触发文件,在想要重启时,修改触发文件来达到触发重启的目的。  
1 spring.devtools.restart.trigger-file =某个文件 
 
Live Reload 插件 Devtools 内置了一个 Live Reload 服务,可以在资源发生改变时来刷新浏览器页面,这个功能需要配合 Live Reload  ,也可以在 Chrome 应用商店中搜索 LiveReload 插件安装。  
全局配置 在 Spring Boot 中,可以通过 properties 文件、YAML 文件、环境变量和命令行参数来设置参数,然后使用 @Value 注解从 Spring 的 Environment 获取参数值,也可以通过 @ConfigurationProperties 注解将值绑定到 Bean 上。  
参数取值途径 以下配置覆盖的优先级顺序由高到低,高优先级的可以覆盖低优先级的形成互补。
当 devtools 激活时,全局配置 ~/.spring-boot-devtools.properties 
@TestPropertySource 测试注解 
@SpringBootTest#properties 测试注解属性 
命令行参数 
SPRING_APPLICATION_JSON 中的属性		 (通过 $ SPRING_APPLICATION_JSON='{"foo":{"bar":"spam"}}' java -jar xxx.jar 设置) 
ServletConfig 初始化参数 
ServletContext 初始化参数 
java:comp/env 中的 JNDI 属性 
Java 系统属性 (System.getProperties()) 
系统环境变量 
RandomValuePropertySource 提供的随机值 
应用之外的 application-{profile}.properties、application.properties 和 YAML 文件 
应用内部的 application-{profile}.properties、application.properties 和 YAML 文件 
带 @Configuration 注解的配置类的 @PropertySource 注解 
通过 SpringApplication.setDefaultProperties 指定的默认属性 
 
@Value 注解  
1 2 3 4 5 6 7 @Component public  class  MyBean  {    @Value("${com.nekolr.name}")      private  String name; } 
 
绑定到 bean 一个一个绑定到对应属性比较麻烦,可以选择直接绑定到 bean 上。  
1 2 3 com.nekolr.name =nekolr com.nekolr.address =nekolr.com 
 
1 2 3 4 5 6 @ConfigurationProperties(prefix = "com.nekolr") public  class  ConfigBean  {    private  String name;     private  String address;      } 
 
设置好配置类后,还需要将配置类添加到入口类上。  
1 2 3 4 5 6 7 8 9 10 @SpringBootApplication @EnableConfigurationProperties({ConfigBean.class}) public  class  DemoApplication  {    public  static  void  main (String[] args)  {         new  SpringApplicationBuilder (DemoApplication.class)                 .bannerMode(Banner.Mode.OFF)                 .run(args);     } } 
 
最后,在需要用到配置类的地方,注入即可使用。  
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 @SpringBootApplication @RestController @EnableConfigurationProperties({ConfigBean.class}) public  class  DemoApplication  {    @Resource      private  ConfigBean configBean;     @RequestMapping("/")      public  String index ()  {         return  "this is index "  + configBean.getName()                  + " "  + configBean.getAddress();     }     public  static  void  main (String[] args)  {         new  SpringApplicationBuilder (DemoApplication.class)                 .bannerMode(Banner.Mode.OFF)                 .run(args);     } } 
 
随机值 Spring Boot 的 RandomValuePropertySource 提供了一些随机值生成,方便开发使用。  
1 2 3 4 5 6 secret =${random.value} number =${random.int} bignumber =${random.long} uuid =${random.uuid} number.less.than.ten =${random.int(10)} number.in.range =${random.int[1024,65536]} 
 
参数引用 1 2 com.nekolr.name =nekolr com.nekolr.address =${com.nekolr.name}.com 
 
自定义配置文件 可以不将配置放在 applcation.properties 文件,使用 PropertySource 指定自定义的配置文件。  
1 2 3 4 5 6 7 8 @Configuration @ConfigurationProperties(prefix = "com.nekolr") @PropertySource("classpath:custom.properties") public  class  ConfigBean  {    private  String name;     private  String address;      } 
 
Profile 多环境 我们知道,在开发时和应用上线运行时,应用具体的配置可能会有所不同,每次修改替换配置文件比较麻烦,此时可以使用 profile 多环境配置。  
除了 application.properties 文件外,还可以设置特定的配置文件,文件的格式为:application-${profile}.properties,比如:application-dev.properties,在 application.properties 中设置 spring.profiles.active=dev 或者通过命令行 java -jar xxx.jar --spring.profiles.active=dev 来指定当前激活的是哪个特定的配置文件。  
也可以使用 @Profile 注解来表明当前配置属于哪个 profile,然后在 application.properties 中设置当前激活哪个环境。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 @PropertySource("classpath:db.properties") @Configuration public  class  DataSourceConfig  {  @Value("${db.user}")    private  String user;   @Value("${db.password}")    private  String password;   @Profile("test")    @Bean("test")    public  DataSource testDataSource (@Value("${db.test.url}")  String url)  {     DataSource  dataSource  =  new  ComboPooledDataSource ();     dataSource.setUser(user);     dataSource.setPassword(password);     dataSource.setUrl(url);     return  dataSource;   }   @Profile("dev")    @Bean("dev")    public  DataSource devDataSource (@Value("${db.dev.url}")  String url)  {     DataSource  dataSource  =  new  ComboPooledDataSource ();     dataSource.setUser(user);     dataSource.setPassword(password);     dataSource.setUrl(url);     return  dataSource;   } } 
 
参考 
Spring Boot 常用配置汇总