保持领先
VMware 提供培训和认证,助力您的职业发展。
了解更多Spring Tool Suite 3.6.4 上周刚刚发布。本博客文章是一篇教程,演示了 STS 提供的一些用于创建和使用 Spring Boot 应用程序的新功能。
在本教程中,您将学习如何
我们使用“New Spring Starter”向导创建一个基本的 Spring Boot 应用程序。
Spring Boot 提供了所谓的“starter”。starter 是一组 classpath 依赖项,与 Spring Boot 自动配置结合使用,无需任何配置即可开始开发应用程序。我们选择“web”starter,因为我们将构建一个简单的“Hello”REST 服务。
该向导是一个 GUI 前端,其底层使用 start.spring.io 的 Web 服务来生成一些基本骨架代码。您可以自己直接使用该 Web 服务,下载生成的 zip 文件,解压并导入等。使用 STS 向导可以通过点击一个按钮完成所有这些操作,并确保项目正确配置,以便您立即开始编码。
点击完成按钮后,您的工作空间将看起来像这样
由 start.spring.io 生成的 HelloBootApplication
Java 主类是目前我们应用中唯一的代码。多亏了 Spring Boot 的“魔力”,并且因为我们在依赖项中添加了“web”starter,这段微小的代码已经是一个功能齐全的 Web 服务器了!只是它还没有任何实际内容。在添加一些内容之前,我们先学习如何运行该应用,并验证它确实正在运行。
通过向导创建的 Spring Boot 应用有两种打包方式:“jar”或“war”。Starter 向导允许您在其“packaging”选项中选择其中一种。Spring Boot 的一个很棒的特性是,您可以轻松创建包含功能齐全嵌入式 Web 服务器的独立“jar”打包项目。要运行您的应用,您只需像运行任何其他普通 Java 应用程序一样运行其 Java Main 类型即可。这是一个巨大的优势,因为您不必费心设置本地或远程 Tomcat 服务器、war 打包和部署。如果您真的想“硬着头皮”这样做,您仍然可以选择“war”打包。但实际上没有必要这样做,因为
注意:我们不会在这里介绍如何将应用部署到 Cloud Foundry,但在本文中,您可以了解更多关于如何使用Cloud Foundry Eclipse 直接从您的 IDE 进行部署的信息。
现在,如果您理解了我刚才所说的,那么您可能会意识到,实际上您不需要 STS 的任何“特殊”工具即可在本地运行该应用。只需点击 Java Main 类型并选择“Run As >> Java Application”即可,瞧。您所有的标准 Eclipse Java 调试工具也将“正常工作”。然而,STS 提供了一个专门的启动器,它基本执行相同操作,但增加了一些有用的附加功能。所以我们来使用它吧。
您的应用应该会启动,您应该能在控制台视图中看到一些输出
您可以在 http://localhost:8080 访问您在本地运行的应用。您将只会看到一个 404
错误页面,但这正是预期结果,因为我们尚未向应用添加任何实际内容。
那么,我承诺的附加功能呢?“Run As >> Boot App”基本上是一个普通的 Java 启动器,但提供了一些额外的选项来自定义它创建的启动配置。要查看这些选项,我们需要打开“Launch Configuration Editor”,可以通过 或
工具栏按钮访问
如果您在 Eclipse 中使用过 Java Launch Configuration Editor,这对您来说应该很熟悉。对于 Boot Launch Configuration,“Main”选项卡有点不同,并有一些额外内容。我不会讨论所有附加内容,您可以在STS 3.6.4 发行说明中了解更多信息。因此,我们只做一个简单的操作,例如,将默认的 HTTP 端口 8080
覆盖为其他端口,如 8888
。您可能猜到这可以通过设置系统属性来完成。在“纯”Java 启动器中,您可以通过命令行参数设置此类属性。但您可能会想,这个属性的名字到底是什么?是“spring.port”、“http.port”还是“spring.server.port”?幸运的是,启动配置编辑器提供了帮助。Override Properties 表提供了一些基本的内容辅助。您只需键入“port”,它就会提供一些建议
选择 server.port
并在右列添加值 8888
,然后点击“Run”。
如果您按照上述步骤严格操作,您的启动可能会立即因异常而终止
Error: Exception thrown by the agent : java.rmi.server.ExportException: Port already in use: 31196; nested exception is:
java.net.BindException: Address already in use
这可能会让您感到有点惊讶,因为我们刚刚修改了端口,不是吗?实际上,这里的端口冲突不是来自 HTTP 端口,而是用于启用“Live Bean Graph Support”的 JMX 端口(我不会在本博客文章中讨论此功能,请参阅STS 3.6.4 发行说明)。
有几种方法可以避免此错误。我们可以再次打开编辑器并更改 JMX 端口,或者禁用“Live Bean Support”。但在此场景下,我们可能确实不想运行应用的多个副本。因此,在启动新实例之前,我们应该停止已运行的实例。由于这是一项非常常见的操作,STS 提供了一个 工具栏按钮专门用于此目的。点击该按钮,正在运行的应用将被停止并重新启动,您刚才对启动配置所做的更改现已生效。如果成功,您现在应该在
http://localhost:8888
(而不是 8080
)看到一个 404
错误页面。(注意:如果您尚未启动任何内容,“重新启动”按钮将不起作用,因为它依赖于您当前会话的启动历史记录。但是,如果您已至少启动过一次应用,则可以“重新启动”已终止的应用)
从启动配置编辑器覆盖默认属性值对于“快速覆盖”很方便,但长期来看,依赖它来配置大量属性和管理更复杂的配置可能不是一个好主意。为此,最好在属性文件中管理属性,您可以将其提交到 SCM。Starter 向导已经为我们方便地创建了一个空的 application.properties
文件。
为了帮助您编辑 application.properties
,STS 3.6.4 提供了一个全新的 Spring Properties 编辑器。该编辑器提供了不错的内容辅助和错误检查功能
上面的截图显示了一些与内容辅助和错误检查相关的“摆弄”。目前对于我们非常简单的“错误页面应用”来说,唯一真正有意义的属性是 server.port
。尝试在属性文件中修改端口,当您再次运行应用时,它应该会自动生效。但是请注意,启动配置中覆盖的属性优先于 application.properties
中的属性。因此,您需要取消勾选或删除启动配置中的 server.port
属性才能看到效果。
我们让应用更有趣一些。以下是我们要做的事情:
要创建 REST 服务,您可以参照本指南。不过,我们要做的事情更简单、更直接。
继续创建一个包含此代码的控制器类
package demo;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@RequestMapping("/hello")
public String hello(@RequestParam String name) {
return "Hello "+name;
}
}
通过重新启动 () 您的应用来尝试一下。URL
http://localhost:8888/hello?name=Kris
应该返回文本消息“Hello Kris”。
这实际上很容易实现,您可能熟悉 Spring 的 @Value 注解。然而,使用 @Value
您将无法获得良好的内容辅助。Spring Properties Editor 不会知道您以这种方式定义的属性。要理解原因,了解 Spring Properties Editor 如何获取已知属性信息是很有用的。
从 1.2.x 版本开始的一些 Spring Boot Jar 包包含特殊的 JSON 元数据文件,编辑器会在您的项目 classpath 中查找并解析这些文件。这些文件包含关于已知配置属性的信息。如果您稍微深入研究一下,可以在 STS 中找到这些文件。例如,打开“spring-boot-autoconfigure-1.2.2.RELEASE.jar”(位于“Maven Dependencies”下),然后浏览到“META-INF/spring-configuration-metadata.json”。您会发现诸如 server.port
等属性在此处有文档说明。
为了让编辑器识别我们自己的用户定义属性,我们必须创建此元数据。幸运的是,只要您使用 Spring Boot @ConfigurationProperties 定义属性,此过程就可以轻松自动化。因此,定义一个如下所示的类
package demo;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties("hello")
public class HelloProperties {
/**
* Greeting message returned by the Hello Rest service.
*/
private String greeting = "Welcome ";
public String getGreeting() {
return greeting;
}
public void setGreeting(String greeting) {
this.greeting = greeting;
}
}
@ConfigurationProperties("hello")
告诉 Boot 获取以 hello.
开头的配置属性,并尝试将它们注入到 HelloProperties
Bean 的相应 Bean 属性中。@Component
注解标记此类,以便 Spring Boot 在扫描 classpath 时能发现它并将其转换为一个 Bean。因此,如果配置文件(或另一个属性源)包含属性 hello.greeting
,则该属性的值将被注入到我们的 HelloProperties
Bean 的 setGreeting
方法中。
现在,要实际使用此属性,我们只需要引用该 bean。例如,要自定义 REST 服务返回的消息,我们可以向 HelloController
添加一个 @Autowired
字段,并调用其 getGreeting
方法
@RestController
public class HelloController {
@Autowired
HelloProperties props;
@RequestMapping("/hello")
public String hello(@RequestParam String name) {
return props.getGreeting()+name;
}
}
再次重新启动您的应用,并尝试访问 http://localhost:8888/hello?name=yourname
。您应该会收到默认的“Welcome yourname”消息。
现在,继续尝试编辑 application.properties
并将 greeting 更改为其他内容。尽管我们已经具备在运行时正确定义属性所需的一切,但您会注意到编辑器仍然不知道我们新创建的属性
要使编辑器感知到这些属性,仍然缺少的是 spring-configuration-metadata.json
文件。此文件在构建时由 spring-boot-configuration-processor
(一个 Java 注解处理器)创建。我们必须将此处理器添加到我们的项目中,并确保在项目构建期间执行它。
将此添加到 pom.xml
中
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>
然后执行“Maven >> Update Project”以触发项目配置更新。STS 提供的 Maven 项目配置器将配置 JDT APT 并激活 Eclipse 构建的处理器。编辑器中的警告将立即消失。您还将获得正确的悬停信息 (Hover Info)
现在注解处理器已激活,将来对 HelloProperties
类进行的任何更改都将触发 json 元数据的自动更新。您可以尝试添加一些额外的属性,或将您的 greeting
属性重命名为其他名称。警告将适时出现/消失。如果您好奇您的元数据文件在哪里,可以在 target/classes/META-INF
中找到它。文件就在那里,尽管 Eclipse 会尽力对您隐藏它。Eclipse 对项目输出文件夹中的所有文件都这样做。不过,您可以通过使用 Navigator
视图来绕过这一点,该视图的文件过滤较少,并向您显示工作空间中实际资源的更直接视图。通过“Window >> Show View >> Other >> Navigator”打开此视图
注意:我们知道手动添加处理器这一步似乎是不必要的复杂操作。我们计划将来进一步自动化此过程。
希望您喜欢本教程。欢迎提出意见和问题。在另一篇即将发布的文章中,我将向您展示 @ConfigurationProperties
更高级的用法以及 STS properties 编辑器如何支持这些用法。