前面我们讲述了如何搭建一个简单的 spring Boot 应用(参见Spring Boot - 初探),这里,我们来学习如何对项目进行相关的配置,包括系统构建、自动配置、依赖注入、开发工具等,使其更好地运行。
为了便于依赖管理,官方建议我们使用Maven或者Gradle,以便进行依赖管理。当然,Spring Boot 也支持其他系统构建方式(如Ant)。 使用 Spring Boot ,你不需要提供相关依赖的版本,Spring Boot 会自动对其进行管理。当你进行系统升级的时候,只需要修改Spring Boot 的版本号就行了,Spring Boot 会自动对其他的依赖进行升级。当然,你也可以根据具体的需要,指定依赖版本来覆盖Spring Boot 的推荐的依赖版本。
我们知道,可以通过继承spring-boot-starter-parent 的方式来添加 Spring Boot 的相关支持,这个父项目为我们提供以下几个默认配置:
POM项目只支持单继承,但有的时候,我们必须要继承其他POM,或者使用我们自己的配置。这时,如果我们要添加 Spring Boot 的支持,可以通过其他方式。
我们可以通过引入spring-boot-dependencies,并且设置scope=import,让Spring Boot来进行依赖管理:
代码清单1 - 将依赖交给Spring Boot管理
<dependencyManagement>
<dependencies>
<dependency>
<!-- Import dependency management from Spring Boot -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>1.3.6.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
我们可以通过在spring-boot-dependencies之前,引入我们需要的依赖的版本来覆盖 Spring Boot 提供的依赖版本,例如:
代码清单2 - 覆盖Spring Boot提供的依赖
<dependencyManagement>
<dependencies>
<!-- Override Spring Data release train provided by Spring Boot -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-releasetrain</artifactId>
<version>Fowler-SR2</version>
<scope>import</scope>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>1.3.6.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
若想使用新的Java编译器版本,可添加一个Java版本的属性,如下:
代码清单3 - 使用较新的Java版本
<properties>
<java.version>1.8</java.version>
</properties>
若要将项目打包成一个可执行的文件,需要在<plugins>中添加 spring-boot-maven-plugin 插件,如下:
代码清单4 - 将项目打包成可执行jar
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
Gradle和Maven不同,没有提供相应的父项目来共享配置,只能通过引入相关的”starter POMs”依赖。spring-boot-gradle-plugin 用于将项目打包成可执行文件,并且将相关依赖交给 Spring Boot 进行管理,其构建项目的脚本如下:
代码清单5 - Gradle构建项目脚本
buildscript {
repositories {
jcenter()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.3.6.RELEASE")
}
}
apply plugin: 'java'
apply plugin: 'spring-boot'
repositories {
jcenter()
}
dependencies {
compile("org.springframework.boot:spring-boot-starter-web")
testCompile("org.springframework.boot:spring-boot-starter-test")
}
我们使用Ant+Ivy同样也能构建一个Spring Boot项目,使用spring-boot-antlib来帮助我们创建一个可执行的jar。 ivy.xml的配置如下:
代码清单6 - ivy.xml
<ivy-module version="2.0">
<info organisation="org.springframework.boot" module="spring-boot-sample-ant" />
<configurations>
<conf name="compile" description="everything needed to compile this module" />
<conf name="runtime" extends="compile" description="everything needed to run this module" />
</configurations>
<dependencies>
<dependency org="org.springframework.boot" name="spring-boot-starter"
rev="${spring-boot.version}" conf="compile" />
</dependencies>
</ivy-module>
build.xml的配置如下:
代码清单7 - build.xml
<project
xmlns:ivy="antlib:org.apache.ivy.ant"
xmlns:spring-boot="antlib:org.springframework.boot.ant"
name="myapp" default="build">
<property name="spring-boot.version" value="1.3.0.BUILD-SNAPSHOT" />
<target name="resolve" description="--> retrieve dependencies with ivy">
<ivy:retrieve pattern="lib/[conf]/[artifact]-[type]-[revision].[ext]" />
</target>
<target name="classpaths" depends="resolve">
<path id="compile.classpath">
<fileset dir="lib/compile" includes="*.jar" />
</path>
</target>
<target name="init" depends="classpaths">
<mkdir dir="build/classes" />
</target>
<target name="compile" depends="init" description="compile">
<javac srcdir="src/main/java" destdir="build/classes" classpathref="compile.classpath" />
</target>
<target name="build" depends="compile">
<spring-boot:exejar destfile="build/myapp.jar" classes="build/classes">
<spring-boot:lib>
<fileset dir="lib/runtime" />
</spring-boot:lib>
</spring-boot:exejar>
</target>
</project>
Starter POMs 是由很多方便的依赖集合组成,如果你需要使用某种技术,通过添加少量的jar就可以把相关的依赖加入到项目中去。 以下是 Spring Boot 应用相关的 Starter POMs 以及说明:
表格1 - Spring Boot 应用相关的 Starter POMs
名称 | 描述 |
---|---|
spring-boot-starter | The core Spring Boot starter, including auto-configuration support, logging and YAML. |
spring-boot-starter-actuator | Production ready features to help you monitor and manage your application. |
spring-boot-starter-amqp | Support for the “Advanced Message Queuing Protocol” via spring-rabbit. |
spring-boot-starter-aop | Support for aspect-oriented programming including spring-aop and AspectJ. |
spring-boot-starter-artemis | Support for “Java Message Service API” via Apache Artemis. |
spring-boot-starter-batch | Support for “Spring Batch” including HSQLDB database. |
spring-boot-starter-cache | Support for Spring’s Cache abstraction. |
spring-boot-starter-cloud-connectors | Support for “Spring Cloud Connectors” which simplifies connecting to services in cloud platforms like Cloud Foundry and Heroku. |
spring-boot-starter-data-elasticsearch | Support for the Elasticsearch search and analytics engine including spring-data-elasticsearch. |
spring-boot-starter-data-gemfire | Support for the GemFire distributed data store including spring-data-gemfire. |
spring-boot-starter-data-jpa | Support for the “Java Persistence API” including spring-data-jpa, spring-orm and Hibernate. |
spring-boot-starter-data-mongodb | Support for the MongoDB NoSQL Database, including spring-data-mongodb. |
spring-boot-starter-data-rest | Support for exposing Spring Data repositories over REST via spring-data-rest-webmvc. |
spring-boot-starter-data-solr | Support for the Apache Solr search platform, including spring-data-solr. |
spring-boot-starter-freemarker | Support for the FreeMarker templating engine. |
spring-boot-starter-groovy-templates | Support for the Groovy templating engine. |
spring-boot-starter-hateoas | Support for HATEOAS-based RESTful services via spring-hateoas. |
spring-boot-starter-hornetq | Support for “Java Message Service API” via HornetQ. |
spring-boot-starter-integration | Support for common spring-integration modules. |
spring-boot-starter-jdbc | Support for JDBC databases. |
spring-boot-starter-jersey | Support for the Jersey RESTful Web Services framework. |
spring-boot-starter-jta-atomikos | Support for JTA distributed transactions via Atomikos. |
spring-boot-starter-jta-bitronix | Support for JTA distributed transactions via Bitronix. |
spring-boot-starter-mail | Support for javax.mail. |
spring-boot-starter-mobile | Support for spring-mobile. |
spring-boot-starter-mustache | Support for the Mustache templating engine. |
spring-boot-starter-redis | Support for the REDIS key-value data store, including spring-redis. |
spring-boot-starter-security | Support for spring-security. |
spring-boot-starter-social-facebook | Support for spring-social-facebook. |
spring-boot-starter-social-linkedin | Support for spring-social-linkedin. |
spring-boot-starter-social-twitter | Support for spring-social-twitter. |
spring-boot-starter-test | Support for common test dependencies, including JUnit, Hamcrest and Mockito along with the spring-test module. |
spring-boot-starter-thymeleaf | Support for the Thymeleaf templating engine, including integration with Spring. |
spring-boot-starter-velocity | Support for the Velocity templating engine. |
spring-boot-starter-web | Support for full-stack web development, including Tomcat and spring-webmvc. |
spring-boot-starter-websocket | Support for WebSocket development. |
spring-boot-starter-ws | Support for Spring Web Services. |
以下是 Spring Boot 帮助项目进行监控和管理的 Starter POMs:
表格2 - Spring Boot 监控、管理相关的 Starter POMs
名称 | 描述 |
---|---|
spring-boot-starter-actuator | Adds production ready features such as metrics and monitoring. |
spring-boot-starter-remote-shell | Adds remote ssh shell support. |
除此之外,Spring Boot 还提供了一些其他方面的技术支持可供选择或者替换的Starter POMs,如下表:
表格3 - Spring Boot 其他方面技术支持的 Starter POMs
名称 | 描述 |
---|---|
spring-boot-starter-jetty | Imports the Jetty HTTP engine (to be used as an alternative to Tomcat). |
spring-boot-starter-log4j | Support the Log4J logging framework. |
spring-boot-starter-logging | Import Spring Boot’s default logging framework (Logback). |
spring-boot-starter-tomcat | Import Spring Boot’s default HTTP engine (Tomcat). |
spring-boot-starter-undertow | Imports the Undertow HTTP engine (to be used as an alternative to Tomcat). |
Spring Boot提供了基于Java类的配置。官方建议使用一个带有@Configuration注解的类来替代XML配置文件进行应用的配置。你可以把配置写入不同的类,然后通过@Import注解导入外部的配置类。如果你一定要使用基于XML文件的配置,那么,你可以在@Configuration类中使用@ImportResource导入XML配置文件。 这里,我们使用一个示例进行说明。
代码清单8 - SubConfiguration.java
import org.springframework.context.annotation.Configuration;
@Configuration
public class SubConfiguration {
...
}
代码清单9 - sub-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
...
</beans>
代码清单10 - Application.java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.ImportResource;
import org.springframework.web.bind.annotation.RestController;
@RestController
@SpringBootApplication
@Import(SubConfiguration.class)
@ImportResource("classpath:config/sub-config.xml")
public class Application {
public static void main(String[] args) {
SpringApplication springApplication =
new SpringApplication(Application.class);
springApplication.run(args);
}
}
Application.java作为主要的类,使用 @Import 和 @ImportResource 分别将外部配置SubConfiguration.java 和 sub-config.xml 进行导入。
Spring Boot 通过项目中添加的依赖自动对应用进行相应的配置。Spring Boot 的自动配置,是通过在配置类上添加@EnableAutoConfiguration 或者 @SpringBootApplication 注解实现的。你也可以在任何地方,定义自己的配置来覆盖Spring Boot的自动配置。 如果你想禁用禁用某些配置,可以通过 @EnableAutoConfiguration 注解的exclude属性来禁用它。如下:
代码清单11 - 禁用指定的配置
package com.example.service;
import org.springframework.boot.autoconfigure.*;
import org.springframework.boot.autoconfigure.jdbc.*;
import org.springframework.context.annotation.*;
@Configuration
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})
public class MyConfiguration {
}
你也可以通过设置配置文件的spring.autoconfigure.exclude属性,来禁用 Spring Boot 的相关配置。 @Configuration, @EnableAutoConfiguration 和 @ComponentScan 经常同时使用,Spring Boot 提供了 @SpringBootApplication 注解,等价于以上三个注解一起使用(这三个注解都是默认值)。
代码清单12 - 使用@SpringBootApplication 注解
package com.example.myproject;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication // same as @Configuration @EnableAutoConfiguration @ComponentScan
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Spring Boot 支持多种运行应用的方式,有如下几种方式: - 直接运行main方法所在的应用入口类 - 作为一个可执行的jar包来运行
$ java -jar target/myproject-0.0.1-SNAPSHOT.jar
或以调试模式运行:
$ java -Xdebug -Xrunjdwp:server=y,transport=dt_socket,address=8000,suspend=n \
-jar target/myproject-0.0.1-SNAPSHOT.jar
$ mvn spring-boot:run
$ gradle bootRun
Spring Boot 提供了一个为开发者服务的模块——spring-boot-devtools,能够提升开发体验。主要包括以下内容:
可以通过以下方式引入spring-boot-devtools: Maven.
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
Gradle.
dependencies {
compile("org.springframework.boot:spring-boot-devtools")
}
程序猿在开发环境进行开发的时候,往往关注的是程序有没有什么问题,而用户则关心的是用户体验,所以,很多参数在开发环境和正式环境是有区别的。spring-boot-devtools 为程序员提供了一些适合开发时的参数默认值,以便于程序员进行开发和查找问题。属性默认值如下:
代码清单13 - spring-boot-devtools 属性默认值
Map<String, Object> properties = new HashMap<String, Object>();
properties.put("spring.thymeleaf.cache", "false");
properties.put("spring.freemarker.cache", "false");
properties.put("spring.groovy.template.cache", "false");
properties.put("spring.velocity.cache", "false");
properties.put("spring.mustache.cache", "false");
properties.put("server.session.persistent", "true");
properties.put("spring.h2.console.enabled", "true");
properties.put("spring.resources.cache-period", "0");
使用了spring-boot-devtools,将会对类路径下的所有文件进行监控,当类路径下面的文件发生更改的时候,应用就会自动重启。其原理是使用了两个classLoader,一个base classloader加载那些不会改变的类(第三方Jar包),另一个classLoader加载频繁更改的类,称为 restart classLoader,这样在有代码更改的时候,原来的 restart classLoader 被丢弃,重新创建一个新的 restart classLoader,由于需要加载的类相比较少,所以实现了较快的重启时间。
当然,并不是所有的更改都需要重启应用(如静态资源、视图模板),我们可以通过设置 spring.devtools.restart.exclude,使这些文件的更改不会触发应用重启。例如,我们要设置/static和/public下的所有文件更新都不触发应用重启:
spring.devtools.restart.exclude=static/**,public/**
如果某个文件不再类路径下,如果其改变了也需要重启应用,你也可以通过设置spring.devtools.restart.additional-paths 属性对其添加监控:
spring.devtools.restart.additional-paths=/restart/**
如果你不需要使用 spring-boot-devtools 提供的自动重启功能,可以通过以下方式禁用重启功能:
代码清单14 - 禁用spring-boot-devtools 自动重启
public static void main(String[] args) {
System.setProperty("spring.devtools.restart.enabled", "false");
SpringApplication.run(MyApp.class, args);
}
通过前面我们知道,spring-boot-devtools 的自动重启功能是通过两个classloader实现的。大多数时候,它可很好的工作,但由于我们的项目是由多个不同的模块组成,如果所有的jar都放到不会改变的base classloader中,有时候也会导致类加载问题。我们可以添加一个文件META-INF/spring-devtools.properties,通过设置以restart.exclude.或者restart.include.为前缀的属性,来手动设置哪些jar需要包含在 restart classloader 中,例如:
restart.include.companycommonlibs=/mycorp-common-[\\w-]+\.jar
restart.include.projectcommon=/mycorp-myproj-[\\w-]+\.jar
对象通过标准的ObjectInputStream反序列化以后,热部署功能就会失效。使用Spring提供的ConfigurableObjectInputStream以及Thread.currentThread().getContextClassLoader() 将会避免此问题的发生。
spring-boot-devtools内嵌了LiveReload的服务,当静态资源发生改变时,也会触发浏览器的刷新。你可以通过安装LiveReload的浏览器扩展来支持该功能,详见 livereload.com 。 如果你不想使用LiveReload,可以通过设置spring.devtools.livereload.enabled=false来禁止LiveReload的服务启用。
在当前用户根目录下添加一个名为.spring-boot-devtools.properties的文件,里面设置的属性将会对所有的使用了spring-boot-devtools的Spring Boot项目生效