Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。通过这种方式,Boot致力于在蓬勃发展的快速应用开发领域(rapid application development)成为领导者。 多年以来,Spring IO平台饱受非议的一点就是大量的XML配置以及复杂的依赖管理。在去年的SpringOne 2GX会议上,Pivotal的CTO Adrian Colyer回应了这些批评,并且特别提到该平台将来的目标之一就是实现免XML配置的开发体验。Boot所实现的功能超出了这个任务的描述,开发人员不仅不再需要编写XML,而且在一些场景中甚至不需要编写繁琐的import语句。在对外公开的beta版本刚刚发布之时,Boot描述了如何使用该框架在140个字符内实现可运行的web应用,从而获得了极大的关注度,该样例发表在tweet上。 然而,Spring Boot并不是要成为Spring IO平台里面众多“Foundation”层项目的替代者。Spring Boot的目标不在于为已解决的问题域提供新的解决方案,而是为平台带来另一种开发体验,从而简化对这些已有技术的使用。对于已经熟悉Spring生态系统的开发人员来说,Boot是一个很理想的选择,不过对于采用Spring技术的新人来说,Boot提供一种更简洁的方式来使用这些技术。 在追求开发体验的提升方面,Spring Boot,甚至可以说整个Spring生态系统都使用到了Groovy编程语言。Boot所提供的众多便捷功能,都是借助于Groovy强大的MetaObject协议、可插拔的AST转换过程以及内置的依赖解决方案引擎所实现的。在其核心的编译模型之中,Boot使用Groovy来构建工程文件,所以它可以使用通用的导入和样板方法(如类的main方法)对类所生成的字节码进行装饰(decorate)。这样使用Boot编写的应用就能保持非常简洁,却依然可以提供众多的功能。 安装Boot从最根本上来讲,Spring Boot就是一些库的集合,它能够被任意项目的构建系统所使用。简便起见,该框架也提供了命令行界面,它可以用来运行和测试Boot应用。框架的发布版本,包括集成的CLI(命令行界面),可以在Spring仓库中手动下载和安装。一种更为简便的方式是使用Groovy环境管理器(Groovy enVironment Manager,GVM),它会处理Boot版本的安装和管理。Boot及其CLI可以通过GVM的命令行 要进行打包和分发的工程会依赖于像Maven或Gradle这样的构建系统。为了简化依赖图,Boot的功能是模块化的,通过导入Boot所谓的“starter”模块,可以将许多的依赖添加到工程之中。为了更容易地管理依赖版本和使用默认配置,框架提供了一个parent POM,工程可以继承它。Spring Boot工程的样例POM文件定义如程序清单1所示。 程序清单1 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven./POM/4.0.0" xmlns:xsi="http://www./2001/XMLSchema-instance" xsi:schemaLocation="http://maven./POM/4.0.0 http://maven./xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>myproject</artifactId> <version>1.0.0-SNAPSHOT</version> <!-- Inherit defaults from Spring Boot --> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.0.0.RC1</version> </parent> <!-- Add typical dependencies for a web application --> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> </dependencies> <repositories> <repository> <id>spring-snapshots</id> <url>http://repo./libs-snapshot</url> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>spring-snapshots</id> <url>http://repo./libs-snapshot</url> </pluginRepository> </pluginRepositories> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project> 为了实现更为简单的构建配置,开发人员可以使用Gradle构建系统中简洁的Groovy DSL,如程序清单1.1所示。 程序清单1.1 buildscript { repositories { maven { url "http://repo./libs-snapshot" } mavenCentral() } dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:1.0.0.RC1") } } apply plugin: 'java' apply plugin: 'spring-boot' repositories { mavenCentral() maven { url "http://repo./libs-snapshot" } } dependencies { compile 'org.springframework.boot:spring-boot-starter-actuator:1.0.0.RC1' } 为了快速地搭建和运行Boot工程,Pivotal提供了称之为“Spring Initializr” 的web界面,用于下载预先定义好的Maven或Gradle构建配置。我们也可以使用Lazybones模板实现快速起步,在执行 开发Spring Boot应用Spring Boot在刚刚公开宣布之后就将一个样例发布到了Twitter上,它目前成为了最流行的一个应用样例。它的全部描述如程序清单1.2所示,一个非常简单的Groovy文件可以生成功能强大的以Spring为后端的web应用。 程序清单1.2 @RestController class App { @RequestMapping("/") String home() { "hello" } } 这个应用可以通过 Boot能够自动确定类所需的功能,这一点使其成为了强大的快速应用开发工具。当应用在Boot CLI中执行时,它们在使用内部的Groovy编译器进行构建,这个编译器可以在字节码生成的时候以编码的方式探查并修改类。通过这种方式,使用CLI的开发人员不仅可以省去定义默认配置,在一定程度上甚至可以不用定义特定的导入语句,它们可以在编译的过程中识别出来并自动进行添加。除此之外,当应用在CLI中运行时,Groovy内置的依赖管理器,“Grape”,将会解析编译期和运行时的类路径依赖,与Boot编译器的自动配置机制类似。这种方式不仅使得框架更加对用户友好,而且能够让不同版本的Spring Boot与特定版本的来自于Spring IO平台的库相匹配,这样一来开发人员就不用关心如何管理复杂的依赖图和版本结构了。另外,它还有助于快速原型的开发并生成概念原型的工程代码。 对于不是使用CLI构建的工程,Boot提供了许多的“starter”模块,它们定义了一组依赖,这些依赖能够添加到构建系统之中,从而解析框架及其父平台所需的特定类库。例如, 为了阐述在Java Maven工程中,如何快速地使Spring Web工程准备就绪,考虑一下程序清单1.3中的应用程序代码。 程序清单1.3 package com.infoq.springboot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.web.bind.annotation.*; @RestController @EnableAutoConfiguration public class Application { @RequestMapping("/") public String home() { return "Hello"; } public static void main(String[] args) { SpringApplication.run(Application.class, args); } } 在 为了发布版本而构建工程时,Boot的Maven和Gradle插件可以嵌入(hook)到这些构建系统的打包过程中,以生成可执行的“胖jar包(fat jar)”,这种jar包含了工程的所有依赖并且能够以可运行jar的方式执行。使用Maven打包Boot应用只需运行 开发微服务Boot对Spring应用的开发进行了简化,提供了模块化方式导入依赖的能力,强调了开发RESTful Web服务的功能并提供了生成可运行jar的能力,这一切都清晰地表明在开发可部署的微服务方面Boot框架是一个强大的工具。正如前面的例子所示,借助于Boot,让一个RESTful Web工程运行起来是一件很容易的事情;不过,为了了解Boot所有潜在的功能,我们会阐述在开发完整功能的微服务时,会遇到的所有繁琐的事情。在企业级基础设施领域,微服务是一种越来越流行的应用架构,因为它能够实现快速开发、更小的代码库、企业级集成以及模块化部署。有众多的框架致力于该领域的开发,该章节将会讨论使用Boot如何简化这一过程。 数据访问我们可以基于各种目的来构建微服务,但有一点是肯定的,那就是大多数都需要读取和写入数据库的能力。Spring Boot使数据库集成变成了一项非常简单的任务,因为它具有自动配置Spring Data以访问数据库的能力。只需在你的工程中将 程序清单1.4 buildscript { repositories { maven { url "http://repo./libs-snapshot" } mavenCentral() } dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:1.0.0.RC1") } } apply plugin: 'groovy' apply plugin: 'spring-boot' repositories { mavenCentral() maven { url "http://repo./libs-snapshot" } } ext { springBootVersion = "1.0.0.RC1" } dependencies { compile 'org.codehaus.groovy:groovy-all:2.2.1' compile "org.springframework.boot:spring-boot-starter-web:$springBootVersion" compile "org.springframework.boot:spring-boot-starter-data-jpa:$springBootVersion" compile "org.springframework.boot:spring-boot-starter-actuator:$springBootVersion" } 在这个配置中,Boot的 程序清单1.5 @Entity class User { @Id @GeneratedValue Long id String username String firstName String lastName Date createdDate Date lastAccessed Boolean isActive = Boolean.TRUE } 为了启用代表 程序清单1.6 insert into user(username, first_name, last_name, created_date) values ('danveloper', 'Dan', 'Woods', now()) 在启动的时候,我们所提供的SQL代码会执行,这样就能确保有一个测试账号可以使用。微服务此时已经具有了数据访问的起始点,程序清单1.7展现了如何按照Spring Data的开发模式创建 程序清单1.7 public interface UserRepository extends CrudRepository<User, Long> { }
程序清单1.8 @RestController @EnableAutoConfiguration @RequestMapping("/user") class UserController { @Autowired UserRepository repository @RequestMapping(method=[RequestMethod.GET]) def get(Long id) { id ? repository.findOne(id) : repository.findAll() } public static void main(String[] args) { SpringApplication.run UserController, args } } 在启动的时候,应用将会输出日志,表明Hibernate按照 在开发微服务应用时,需要特别注意的一点是使用了 微服务所提供的数据并不一定全部适合关系型结构,针对这一点Spring Boot也暴露了一些模块,从而让开发人员可以使用Spring Data的MongoDB和Redis项目,不过依然采取特定的方式来进行配置。Spring Data用来定义数据访问对象(Data Access Object)的高层框架,这样快速切换JPA与非JPA数据源会变得非常容易。参见程序清单1.9,它展现了一个重新定义的 程序清单1.9 public interface UserRepository extends MongoRepository<User, Long> { }
程序清单1.10 dependencies { compile 'org.codehaus.groovy:groovy-all:2.2.1' compile "org.springframework.boot:spring-boot-starter-web:$springBootVersion" compile "org.springframework.boot:spring-boot-starter-data-mongodb:$springBootVersion" compile "org.springframework.boot:spring-boot-starter-actuator:$springBootVersion" } MongoDB依赖都置于classpath之中以后,Boot将会自动配置Spring Data连接到localhost上的数据库,并且默认的数据库名为 程序清单1.11 @RestController @RequestMapping("/user") @EnableAutoConfiguration class UserController { @Autowired UserRepository repository @RequestMapping(method=[RequestMethod.GET]) def get(Long id) { id ? repository.findOne(id) : repository.findAll() } @RequestMapping(method=[RequestMethod.POST]) def create(@RequestBody User user) { repository.save user user } public static void main(String[] args) { SpringApplication.run UserController, args } } 当微服务的使用者往应用的端点上发送一个HTTP POST请求时,Spring将会把请求体转换为 程序清单1.12 curl -v -H "Content-Type: application/json" -d "{ \"username\": \"danveloper\", \"firstName\": \"Dan\", \"lastName\": \"Woods\", \"createdDate\": \"2014-02-02T00:00:00\" }" http://localhost:8080/user 按照Boot针对Mongo数据源的特定配置,新的 配置我们可以很快地重写Spring Boot的默认配置。默认情况下,应用的配置可以使用Java属性文件来进行定义,这个文件名为 程序清单1.13 # Server settings (ServerProperties) server: port: 8080 address: 127.0.0.1 sessionTimeout: 30 contextPath: / # Tomcat specifics tomcat: accessLogEnabled: false protocolHeader: x-forwarded-proto remoteIpHeader: x-forwarded-for basedir: backgroundProcessorDelay: 30 # secs 允许重写Boot的自动化配置,这一点能够使你的应用从原型转化为真正的产品,Boot使用相同的 程序清单1.14 spring: datasource: driverClassName: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/proddb username: root password 在一些场景下你可能需要更为灵活的配置,Boot允许你通过Java的系统属性(System properties)重写很多它的默认配置。例如,如果你的应用需要在部署到产品化环境中使用不同的数据库用户,那么username配置指令可以通过标准的Java系统属性传入到应用之中,而这需要切换到命令行中执行 外部化配置微服务必须要支持的很重要的一点就是外部化配置。这种配置可以包含任何的内容,从占位符信息到数据库配置等等,在初始规划和构建应用原型时,这是必须要考虑的架构内容。在Spring IO平台中,已经存在各种导入配置的策略,但是应用能够以多种方式使用配置所造成的后果往往是产生冗长的编码性耦合。 Boot一个很棒的特性在于它能管理外部化的配置并将其转换为对象结构,这个对象可以在整个应用上下文中使用。创建一个简单老式的Java/Groovy对象(Plain Old Java/Groovy Object),并使用 程序清单1.15 @ConfigurationProperties(name = "application") class ApplicationProperties { String name String version } 当 程序清单1.16 application: name: sb-ms-custdepl version: 0.1-CUSTOMER 这些配置指令可以有各种用途,要访问这些指令的唯一要求就是代表它们的POJO/POGO必须是Spring应用上下文的成员。Boot能够将一个controller作为Spring Java配置对象,这样就能很容易地管理配置bean与应用上下文的集成,如程序清单1.17所示。 程序清单1.17 @RestController @Configuration @RequestMapping("/appinfo") @EnableAutoConfiguration class AppInfoController { @Autowired ApplicationProperties applicationProperties @RequestMapping(method=[RequestMethod.GET]) def get() { [ name: applicationProperties.name, version: applicationProperties.version ] } @Bean ApplicationProperties applicationProperties() { new ApplicationProperties() } public static void main(String[] args) { SpringApplication.run UserController, args } } 程序清单1.17中的样例代码可能有些牵强,不过,即便是在更为复杂的场景下,如何使用Boot来访问应用特定配置的原则是相同的。配置类也支持嵌套式的对象图,这样来自于配置中的深层数据就能更便利地进行访问,也有了更好的语义。例如,如果我们想要得到的配置指令是 程序清单1.18 @ConfigurationProperties(name = "application") class ApplicationProperties { String name String version final Metrics metrics = new Metrics() static class Metrics { String dbExecutionTimeKey } } 现在,我们的 程序清单1.19 application: name: sb-ms-custdepl version: 0.1-CUSTOMER metrics: dbExecutionTimeKey: user.get.db.time 当我们需要访问 为了在整个应用之中使用 程序清单1.20 @RestController @RequestMapping("/user") @EnableAutoConfiguration class UserController { @Autowired UserRepository repository @Autowired GaugeService gaugeService @Value('${application.metrics.dbExecutionTimeKey}') String dbExecutionKey @RequestMapping(method=[RequestMethod.GET]) def get(Long id) { def start = new Date().time def result = id ? repository.findOne(id) : repository.findAll() gaugeService.submit dbExecutionKey, new Date().time - start result } public static void main(String[] args) { SpringApplication.run UserController, args } } 关于应用指标的报告,后面会有更为详细的介绍,但现在重要的一点在于,理解 安全在微服务的开发中,对于完备安全场景的需求会持续增长。为了满足这种需求,Boot引入了强大完整的Spring Security,并且提供了自动配置的功能,以快速简便地启用安全层。只需在应用的classpath中包含 程序清单1.21 security: basic: enabled: true Boot会为你提供一个默认的用户账号 程序清单1.22 security: basic: enabled: true user: name: secured password: foo 对于简单的内部应用或开发原型来说,Boot内置的基础设施能够快速地在微服务中启用基本认证,这是非常有用的。随着需求的演化,你的应用毫无疑问会需要更细粒度的安全特性,如保护端点只能由特定的角色访问。从这个角度来看,我们可能希望具有 程序清单1.23 @RestController @RequestMapping("/user") @Configuration @EnableGlobalMethodSecurity(securedEnabled = true) @EnableAutoConfiguration class UserController extends WebSecurityConfigurerAdapter { @Autowired UserRepository repository @RequestMapping(method = [GET]) @Secured(['ROLE_USER']) def get(Long id) { id ? repository.findOne(id) : repository.findAll() } @RequestMapping(method = [POST]) @Secured(['ROLE_ADMIN']) def create(@RequestBody User user) { repository.save user user } @Override void configure(AuthenticationManagerBuilder auth) { auth .inMemoryAuthentication() .withUser "user" password "password" roles "USER" and() withUser "admin" password "password" roles "USER", "ADMIN" } @Override void configure(HttpSecurity http) throws Exception { BasicAuthenticationEntryPoint entryPoint = new BasicAuthenticationEntryPoint() entryPoint.realmName = "Spring Boot" http.exceptionHandling().authenticationEntryPoint(entryPoint) http.requestMatchers().antMatchers("/**").anyRequest() .and().httpBasic().and().anonymous().disable().csrf().disable() } public static void main(String[] args) { SpringApplication.run UserController, args } } 在程序清单1.23的样例之中,应用现在被明确地配置为要基于 对于微服务来说,基本认证是很好的一个选择,因为它遵循了很实用且广泛使用的认证协议。换句话说,很多的API调用者,包括移动应用,能够很容易地使用这一点来访问你的微服务。当你的认证需求超过了基本认证的功能时(如OpenID或OAuth),微服务可以使用Spring Security的全部功能来满足你的需求。 消息集成在任何的应用中,消息(messaging)都是一种很强大的工具,在一点上,微服务当然也不能例外。使用消息驱动架构开发的应用能够更好地支持可重用性和扩展性。Spring Boot能够让开发人员在编写微服务时将消息作为架构的核心组成部分,它使用到了Spring IO平台的企业集成模式(Enterprise Integration Patterns)实现,即Spring Integration。Spring Integration提供了开发消息驱动架构的基本结构,以及与分布式企业平台集成的模块。这种能力使得微服务可以使用来自抽象消息源的业务对象,这些消息源可以在应用内部,也可能是组织机构内部的其他服务所提供的。 尽管Boot并没有提供明确的Spring上下文自动化配置,但是它为Spring Integration提供了一个starter模块,它会负责引入Spring Integration项目的一系列依赖。这些依赖包括Spring Integration的核心库(Core library)、HTTP模块(用来进行面向HTTP的企业集成)、IP模块(用来进行基于Socket的集成操作)、File模块(用于进行文件系统集成)以及Stream模块(用于支持使用Stream的操作,如stdin和stdout)。这个starter模块为开发人员提供了健壮的消息功能的工具集,可以使已有的基础设施适应微服务API。 除了starter模块,Boot也为通过CLI构建的应用提供了编译器自动配置的功能。对于需要快速构建微服务原型并验证可行性的开发者来说,这种方式提供了一些捷径。使用企业级平台的应用可以快速地进行开发,在转移到正式的工程和构建系统之前,就能确认其价值。使用Spring Boot和Spring Integration使一个消息驱动的微服务运行起来非常简单,如程序清单1.24的样例代码所示。 程序清单1.24 @RestController @EnableIntegrationPatterns class App { @Bean def userLookupChannel() { new DirectChannel() } @Bean def userTemplate() { new MessagingTemplate(userLookupChannel()) } @RequestMapping(method=[RequestMethod.GET]) def get(@RequestParam(required=false) Long id) { userTemplate().convertSendAndReceive( id ? id : "") } } class User { Long id } @MessageEndpoint class UserLookupObject { @ServiceActivator(inputChannel="userLookupChannel") def get(Long id) { id ? new User(id:id) : new User() } } 使用消息驱动的方式来进行微服务的开发能提供很大的代码可重用性,并且能够与底层的服务提供者实现相解耦。在更为正式的场景之中,程序清单1.24的代码可能会负责组合数据,这些数据可能来自于数据库调用和企业组织中某个外部的服务集成。Spring Integration具有内置的设施用来进行负载路由(payload routing)和处理器链(handler chaining),这对于组合不同的数据来说,是一个很有吸引力的方案,我们的微服务可以作为一个数据的提供者(provider)。 提供度量指标微服务最重要的一个特性可能就是为报表终端(reporting agent)提供度量指标。不像那些功能完备的Web应用,微服务是轻量级的,设计时可能就不会规划提供报表界面或完备的接口来分析服务的活动。这种类型的操作最好是留给专门进行数据聚合和分析的应用,这些数据能够用来进行稳定性、性能以及商务智能的监控。基于这样的前提,微服务应该为这些工具提供端点,从而更加容易地获取有关该服务活动的数据。而报表工具负责将数据聚合到一个视图或报告中,对于关心数据的人这才是有意义的。 微服务的一些指标如稳定性和性能,对所有的应用都是通用的,但是与业务操作相关的指标必须由应用本身来具体进行管理。针对这一点,Spring Boot的 程序清单1.25 @RestController @RequestMapping("/user") @EnableAutoConfiguration class UserController { @Autowired UserRepository repository @Autowired CounterService counterService @RequestMapping(method = [GET]) def get() { get(null) } @RequestMapping(value="/{id}", method = [GET]) def get(@PathVariable Long id) { counterService.increment id ? "queries.by.id.$id" : "queries.without.id" id ? repository.findOne(id) : repository.findAll() } } 在点击 gauge是稍微有所不同的一种类型指标,它会进行探索性的计算或基于请求来确定值。如 程序清单1.26 @RestController @RequestMapping("/user") @EnableAutoConfiguration class UserController { @Autowired UserRepository repository @Autowired CounterService counterService @RequestMapping(method = [GET]) def get() { get(null) } @RequestMapping(value="/{id}", method = [GET]) def get(@PathVariable Long id) { def start = new Date().time def result = id ? repository.findOne(id) : repository.findAll() def time = new Date().time - start gaugeService.submit("user.get.db.time", time.doubleValue()) result } } 默认情况下,指标会存储在一个易失的内存数据库之中,但Boot同时也为应用上下文提供了 Boot还提供了对Coda Hale Metrics库的支持,它会将以特定名称开头的指标强制转换为对应的Metrics类型。例如,如果有一个指标是以 一旦微服务的指标在Boot中进行了注册,那么报表工具就可以通过 打包Boot应用正如前面所讨论的,Boot提供了Maven和Gradle插件,它为构建系统的打包阶段提供了一种钩子(hook),以产生所谓的“胖jar”,在这种jar中包含了工程的所有依赖。当这个胖jar包执行时,应用将会运行在与工程开发期相同的嵌入式容器之中。这种简便的方式能够让开发人员省去很多麻烦,因为他们的部署包在开发期和运行时环境之中具有相同的依赖结构。这也能够缓解运维团队的焦虑,他们不用担心部署的场景,因为在部署时一个错误配置的运行时容器可能会带有某个特定的依赖,而在项目的开发期所依赖的可能是另外一个。 为了在Maven下执行打包,只需执行 打包完成之后,胖jar包就能够像其他可运行的jar文件那样在命令行中执行了,也就是使用 对于需要部署到传统servlet容器之中的应用,Boot提供了一种方式以编码的方式初始化Web配置。为了使用这一点,Boot提供了可选的 程序清单1.27 @RestController @EnableAutoConfiguration class Application extends SpringBootServletInitializer { @RequestMapping(method = RequestMethod.GET) String get() { "home" } static void main(String[] args) { SpringApplication.run this, args } @Override SpringApplicationBuilder configure(SpringApplicationBuilder application) { application.sources Application } }
当将应用打包部署到servlet容器之中时,工程要构建为一个war文件。在Maven工程中,为了适应这一点,需要移除Boot插件,并且packaging需要明确定义为“war”类型,如程序清单1.28所示。 程序清单1.28 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven./POM/4.0.0" xmlns:xsi="http://www./2001/XMLSchema-instance" xsi:schemaLocation="http://maven./POM/4.0.0 http://maven./xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>myproject</artifactId> <version>1.0.0-SNAPSHOT</version> <packaging>war</packaging> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.0.0.RC1</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> </dependencies> <repositories> <repository> <id>spring-snapshots</id> <url>http://repo./libs-snapshot</url> </repository> </repositories> </project> 对这个工程执行 程序清单1.29 apply plugin: 'java' apply plugin: 'war' repositories { mavenCentral() maven { url "http://repo./snapshot" } maven { url "http://repo./milestone" } } ext { springBootVersion = '1.0.0.BUILD-SNAPSHOT' } dependencies { compile "org.springframework.boot:spring-boot-starter-web:${springBootVersion}" compile "org.springframework.boot:spring-boot-starter-actuator:${springBootVersion}" } 对于Boot工程,使用这个构建脚本运行Gradle的 不管是Maven还是Gradle的配置,一旦war文件产生,它就可以部署到任意兼容Servlet 3.0的应用服务器之中。部分兼容的容器包括Tomcat 7+、Jetty 8、Glassfish 3.x、JBoss AS 6.x/7.x以及Websphere 8.0。 延伸阅读Spring Boot团队已经编写了完整的指导和样例来阐述框架的功能。Blog文章、参考资料以及API文档都可以在Spring.IO网站上找到。项目的GitHub页面上可以找到示例的工程,更为具体的细节可以阅读Spring Boot的参考手册。SpringSourceDev YouTube频道有一个关于Spring Boot的webinar,它概述了这个项目的目标和功能。在去年在伦敦举行的Groovy & Grails Exchange上,David Dawson做了一个使用Spring Boot开发微服务的演讲。 |
|