领先一步
VMware提供培训和认证,以加速您的进步。
了解更多Spring Tool Suite 3.6.4 上周刚刚发布。这篇博文是一个教程,演示了 STS 提供的一些新功能,用于创建和使用 Spring Boot 应用程序。
在本教程中,您将学习如何
我们使用“新建 Spring 启动器”向导来创建一个基本的 Spring Boot 应用程序。
Spring Boot 提供了所谓的“启动器”。启动器是一组类路径依赖项,这些依赖项与 Spring Boot 自动配置一起,使您能够在无需进行任何配置的情况下开始使用应用程序。我们选择“Web”启动器,因为我们将构建一个简单的“Hello”REST 服务。
该向导是一个 GUI 前端,在后台,它使用 start.spring.io 上的 Web 服务生成一些基本脚手架。您可以直接使用 Web 服务,下载它生成的 zip 文件,解压缩它,导入它等等。使用 STS 向导可以一键完成所有这些操作,并确保项目配置正确,以便您可以立即开始编码。
单击“完成”按钮后,您的工作区将如下所示
目前,由 start.spring.io 生成的HelloBootApplication
Java 主类是应用程序中唯一的代码。由于 Spring Boot 的“魔力”,并且因为我们在依赖项中添加了“Web”启动器,所以这小段代码已经是一个功能齐全的 Web 服务器!它只是还没有任何实际内容。在添加一些内容之前,让我们学习如何运行该应用程序,并验证它确实在进程中运行。
由向导创建的 Spring Boot 应用程序有两种类型:“jar”或“war”。启动器向导允许您在其“打包”选项中在这两者之间进行选择。Spring Boot 的一个很棒的功能是,您可以轻松创建包含完全功能的嵌入式 Web 服务器的独立“jar”打包项目。要运行您的应用程序,您只需运行其 Java 主类型,就像运行任何其他普通 Java 应用程序一样。这是一个巨大的优势,因为您不必费心设置本地或远程 Tomcat 服务器、war 打包和部署。如果您真的想“以硬的方式”做事,您仍然可以选择“war”打包。但是,实际上没有必要这样做,因为
注意:我们不会在此处介绍如何将应用程序部署到 Cloud Foundry,但在本文中,您可以了解有关使用Cloud Foundry Eclipse直接从您的 IDE 执行此操作的更多信息。
现在,如果您理解了我刚才说的话,那么您可能已经意识到,您实际上并不需要 STS 的任何“特殊”工具来在本地运行该应用程序。只需单击 Java 主类型并选择“以...方式运行 > Java 应用程序”,瞧。此外,您所有标准的 Eclipse Java 调试工具都将“正常工作”。但是,STS 提供了一个专门的启动器,它基本上执行相同操作,但添加了一些有用的额外功能。所以让我们改为使用它。
您的应用程序应该启动,您应该在控制台视图中看到一些输出
您可以通过 https://127.0.0.1:8080 打开您在本地运行的应用程序。您只会看到一个404
错误页面,但这正是预期的,因为我们还没有向应用程序添加任何实际内容。
现在,我承诺的额外功能是什么?“以...方式运行 > Boot 应用程序”几乎是一个普通的 Java 启动器,但提供了一些额外的选项来自定义它创建的启动配置。要查看这些选项,我们需要打开“启动配置编辑器”,可以通过 或 工具栏按钮访问
如果您在 Eclipse 中使用过 Java 启动配置编辑器,那么这应该看起来很熟悉。对于 Boot 启动配置,“主”选项卡略有不同,并且有一些额外的内容。我不会讨论所有额外内容,您可以在STS 3.6.4 发行说明中了解更多信息。因此,让我们只做一些简单的事情,例如,将默认 http 端口8080
覆盖为其他端口,例如8888
。您可能已经猜到,这可以通过设置系统属性来完成。在“纯”Java 启动器中,您可以通过命令行参数设置此类属性。但是,您可能想知道,该属性的确切名称是什么“spring.port”、“http.port”、“spring.server.port”?幸运的是,启动配置编辑器可以提供帮助。“覆盖属性”表提供了一些基本的内容辅助。您只需键入“port”,它就会给出一些建议
选择server.port
,在右侧列中添加值8888
,然后单击“运行”。
如果您完全按照步骤操作到目前为止,您的启动可能会立即以异常终止
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 端口,而是用于启用“实时 Bean 图支持”的 JMX 端口(我不会在这篇博文中讨论此功能,请参阅STS 3.6.4 发行说明)。
我们可以做一些事情来避免错误。我们可以再次打开编辑器并更改 JMX 端口,或者我们可以禁用“实时 Bean 支持”。但可能我们真的不想在这种情况下运行多个应用程序副本。因此,我们应该在启动新副本之前停止已运行的副本。由于这是如此常见的事情,因此 STS 提供了一个 工具栏按钮,专门用于此目的。单击该按钮,正在运行的应用程序将停止并重新启动,您刚刚对启动配置所做的更改将生效。如果成功,您现在应该在https://127.0.0.1:8888
而不是8080
处看到一个404
错误页面。(注意:如果您尚未启动任何内容,则“重新启动”按钮将不起作用,因为它从您当前会话的启动历史记录中工作。但是,如果您至少启动了一个应用程序,则可以“重新启动”已终止的应用程序)
从启动配置编辑器覆盖默认属性值对于“快速覆盖”很方便,但长期依赖它来配置许多属性和管理更复杂的配置可能不是一个好主意。为此,最好在属性文件中管理属性,您可以将其提交到 SCM。启动器向导已经为我们方便地创建了一个空的application.properties
。
为了帮助您编辑application.properties
,STS 3.6.4 提供了一个全新的 Spring 属性编辑器。该编辑器提供了良好的内容辅助和错误检查
上面的屏幕截图显示了一些“乱七八糟”的内容辅助和错误检查。目前,对于我们非常简单的“错误页面应用程序”,唯一真正有意义的属性是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 `https://127.0.0.1:8888/hello?name=Kris` 应该返回文本消息“Hello Kris”。
这实际上非常容易做到,您可能熟悉Spring的@Value注解。但是,使用`@Value`,您将无法获得良好的代码提示。Spring属性编辑器将不会知道您以这种方式定义的属性。要了解原因,了解Spring属性编辑器如何获取有关已知属性的信息非常有用。
从1.2.x版本开始,一些Spring Boot Jar包含特殊的JSON元数据文件,编辑器会在您的项目类路径上查找并解析这些文件。这些文件包含有关已知配置属性的信息。如果您稍微深入研究一下,可以从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在扫描类路径时将其识别并将其转换为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;
}
}
再次重新启动应用程序,并尝试访问`https://127.0.0.1:8888/hello?name=yourname`。您应该会收到默认的“Welcome yourname”消息。
现在,尝试编辑`application.properties`并将问候语更改为其他内容。尽管我们已经准备就绪,可以在运行时正确定义属性,但您会注意到编辑器仍然不知道我们新创建的属性。
要使编辑器能够识别该属性,还需要`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构建激活处理器。编辑器中的警告将立即消失。您还将获得正确的悬停信息。
现在注解处理器已被激活,对`HelloProperties`类的任何未来更改都将触发JSON元数据的自动更新。您可以通过添加一些额外的属性或将`greeting`属性重命名为其他名称来进行尝试。警告将根据需要显示/消失。如果您好奇元数据文件在哪里,可以在`target/classes/META-INF`中找到它。该文件在那里,即使Eclipse尽最大努力将其隐藏起来。Eclipse对项目输出文件夹中的所有文件都执行此操作。但是,您可以通过使用“Navigator”视图来解决此问题,该视图不会过滤太多文件,并为您提供工作区中实际资源的更直接视图。通过“Window >> Show View >> Other >> Navigator”打开此视图。
注意:我们知道手动添加处理器的步骤似乎是一个不必要的复杂操作。我们计划在将来进一步自动化此操作。
希望您喜欢本教程。欢迎评论和提问。在即将发布的另一篇文章中,我将向您展示`@ConfigurationProperties`的更多高级用法以及STS属性编辑器如何支持它。