The opening words
Spring Boot Actuator is Spring Boot subprojects. It adds several production-level service for your application, which does not require much effort you pay can be achieved. In this tutorial, you will build a application to add these services.
Your application will be created
The guide will guide you to create a "Hello, world" RESTful Web services using Spring Boot Actuator. We will build a HTTP GET request to accept service of the following:
$ curl http://localhost:9000/hello-world
It responds to the following JSON data:
{"id":1,"content":"Hello, World!"}
Application also added many features for the production (or other) environment management services. We build business function services and functions to build RESTful Web services are the same. Although the comparison may be very interesting, but we do not need to complete the guide means that guide.
Tools you will need
- Probably about 15 minutes;
- Your favorite text editor or integrated development environment (IDE)
- JDK 1.8 or later;
- Gradle 4+ or Maven 3.2+
- You can also code directly into the IDE:
How to complete this guide
Like most of Spring Getting Started Like, you can start from scratch and complete each step, you can bypass you are already familiar with the basic setup steps. Such as which way on the code you can finally have a job.
- To start from scratch, venue to start Initializr from the Spring ;
- To skip foundation, do the following:
- Download and decompress the guide used in the source code , or by means of its cloning operations Git:
git clone https://github.com/spring-guides/gs-actuator-service.git
- Switch to
gs-actuator-service/initial
the directory; - Jump to the guidelines created to show classes .
- Download and decompress the guide used in the source code , or by means of its cloning operations Git:
After everything is ready, you can check gs-actuator-service/complete
the code directory.
From the beginning of Spring Initializr
For all of Spring applications, you should from Spring Initializr start. Initializr provides a quick way to extract the required application depends, and completed a number of settings for you. The example requires Spring Boot Actuator and Spring Web dependent. The following figure shows the example provided Initializr item:
The figure shows the selection as Initializr Maven build tool. You can also use Gradle. It also
com.example
andactuator-service
values are shown as Group and Artifact. In the remainder of this example, these values will be used.
The following list shows the creation of the choice Maven pom.xml
file:
<?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 https://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>2.2.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>actuator-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>actuator-service</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-actuator</artifactId>
</dependency>
<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>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
The following list shows the creation of Gradle when selecting build.gradle
files:
plugins {
id 'org.springframework.boot' version '2.2.2.RELEASE'
id 'io.spring.dependency-management' version '1.0.8.RELEASE'
id 'java'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
}
test {
useJUnitPlatform()
}
Run empty Service
Spring Initializr create an empty application, we can use it to get started. The following example (from the initial
catalog src/main/java/com/example/actuatorservice/ActuatorServiceApplication
) shows the class Spring Initializr created:
package com.example.actuatorservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ActuatorServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ActuatorServiceApplication.class, args);
}
}
@SpringBootApplication
Annotations provide a default value (e.g., an embedded servlet container) loading the contents of the classpath and other content. It also enabled the Spring MVC @EnableWebMvc
annotation, the annotation will activate the Web endpoint.
Endpoint is not defined in this application, but there is enough to start the endpoint of things and see some of the features of the Actuator. SpringApplication.run()
Command knows how to start the Web application. We need to do is run the following command:
$ ./gradlew clean build && java -jar build/libs/gs-actuator-service-0.1.0.jar
由官网提供的以上这条命令的执行结果与我本地的不一样,我需要这样才能运行:
./gradlew clean build && java -jar build/libs/actuator-service-0.0.1-SNAPSHOT.jar
。
我们尚未编写任何代码,打开另一个终端,然后尝试以下命令(及其输出显示):
$ curl localhost:8080
{"timestamp":1384788106983,"error":"Not Found","status":404,"message":""}
以上命令的输出表明服务器正在运行,但是我们尚未定义任何业务端点。我们会看到来自 Actuator /error 端点的通用 JSON 响应,而不是默认的容器生成的 HTML 错误响应。我们可以在服务器启动的控制台日志中看到开箱即用提供的端点。我们可以尝试其中的一些端点,包括 /health 端点。以下示例显示了如何执行该操作:
$ curl localhost:8080/actuator/health
{"status":"UP"}
状态为 UP
,因此 actuator 服务正在运行。
有关更多详细信息,请参见 Spring Boot 的 Actuator 项目。
创建展示类
首先,我们需要考虑一下 API 的外观。
我们想要处理 /hello-world
的 GET 请求,可以选用使用名称查询参数。为了响应这样的请求,我们想发送回表示问候的 JSON,该 JSON 类似于以下内容:
{
"id": 1,
"content": "Hello, World!"
}
id
字段是问候语的唯一标识符,content
包含问候语的文本展示。
要建模问候展示,创建一个展示类。以下清单(来自 src/main/java/com/example/actuatorservice/Greeting.java
)显示了 Greeting
类:
package com.example.actuatorservice;
public class Greeting {
private final long id;
private final String content;
public Greeting(long id, String content) {
this.id = id;
this.content = content;
}
public long getId() {
return id;
}
public String getContent() {
return content;
}
}
现在,我们需要创建用于展示类的端点控制器。
创建资源控制器
在 Spring 中,REST 端点是 Spring MVC 控制器。以下 Spring MVC 控制器(来自 src/main/java/com/example/actuatorservice/HelloWorldController.java
)处理针对 /hello-world
端点的 GET 请求并返回 Greeting
资源:
package com.example.actuatorservice;
import java.util.concurrent.atomic.AtomicLong;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class HelloWorldController {
private static final String template = "Hello, %s!";
private final AtomicLong counter = new AtomicLong();
@GetMapping("/hello-world")
@ResponseBody
public Greeting sayHello(@RequestParam(name="name", required=false, defaultValue="Stranger") String name) {
return new Greeting(counter.incrementAndGet(), String.format(template, name));
}
}
面向用户的控制器和 REST 端点控制器之间的主要区别在于响应的创建方式。端点控制器不依赖于视图(如 JSP)以 HTML 形式呈现模型数据,而是将要直接写入响应正文的数据返回。
@ResponseBody
注解告诉 Spring MVC 不要将模型呈现到视图中,而是将返回的对象写到响应主体中。它是通过使用 Spring 的某一个消息转换器来实现的。由于 Jackson 2 在类路径中,因此如果请求的 Aceept
标头指定应返回 JSON,则 MappingJackson2HttpMessageConverter
将 Greeting
对象转换成 JSON。
如何获知 Jackson 2 的类路径?运行
mvn dependency:tree
或./gradlew dependencies
, 然后我们将获得包含 Jackson 2.x 的详细依赖关系树。我们还可以看到它来自 /spring-boot-starter-json,它本身是由 spring-boot-starter-web 导入的。
运行应用
我们可以从自定义主类或直接从其中一个配置类运行应用。对于这个简单的示例,可以使用 SpringApplication
帮助类。请注意,这是 Spring Initializr 为我们创建的应用类,我们甚至无需对其进行修改即可使其适用于该简单应用。以下清单(来自 src/main/java/com/example/actuatorservice/HelloWorldApplication.java
)显示了应用类:
package com.example.actuatorservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class HelloWorldApplication {
public static void main(String[] args) {
SpringApplication.run(HelloWorldApplication.class, args);
}
}
在常规的 Spring MVC 应用中,我们将添加 @EnableWebMvc
来激活关键行为,包括配置 DispatcherServlet
。但是当 Spring Boot 在我们的类路径上监测到 spring-webmvc 时,它会自动开启该注解。这使我们可以在接下来的步骤中构建控制器。
@SpringBootApplication
注解还引入了 @ComponentScan
注解,该注解告诉 Spring 扫描 com.example.actuatorservice
应用包中的那些控制器(以及任何其他带有注解的组件类)。
构建可执行 JAR
我们可以结合 Gradle 或 Maven 来从命令行运行该应用。我们还可以构建一个包含所有必须依赖项、类以及资源的可执行 JAR 文件,然后运行该文件。在整个开发生命周期中,跨环境等等情况下,构建可执行 JAR 可以轻松地将服务作为应用进行发布、版本化以及部署。
如果使用 Gradle,则可以借助 ./gradlew bootRun
来运行应用。或通过借助 ./gradlew build
来构建 JAR 文件,然后运行 JAR 文件,如下所示:
java -jar build/libs/gs-actuator-service-0.1.0.jar
由官网提供的以上这条命令的执行结果与我本地的不一样,我需要这样才能运行:
java -jar build/libs/actuator-service-0.0.1-SNAPSHOT.jar
。
如果使用 Maven,则可以借助 ./mvnw spring-boot:run
来运行该用。或可以借助 ./mvnw clean package
来构建 JAR 文件,然后运行 JAR 文件,如下所示:
java -jar target/gs-actuator-service-0.1.0.jar
由官网提供的以上这条命令的执行结果与我本地的不一样,我需要这样才能运行:
java -jar target/actuator-service-0.0.1-SNAPSHOT.jar
。
我们还可以构建一个经典的 WAR 文件。
服务运行后(因为我们在终端上运行 spring-boot:run
),可以通过在单独的终端上运行以下命令来对其进行测试:
$ curl localhost:8080/hello-world
{"id":1,"content":"Hello, Stranger!"}
切换至不一样的服务器端口
Spring Boot Actuator 默认在端口 8080 上运行。通过添加 application.properties
文件,我们可以覆盖该设置。以下清单(来自 src/main/resources/application.properties
)显示了必要的更改:
server.port: 9000
management.server.port: 9001
management.server.address: 127.0.0.1
通过在终端中运行以下命令来再次运行服务器:
$ ./gradlew clean build && java -jar build/libs/gs-actuator-service-0.1.0.jar
由官网提供的以上这条命令的执行结果与我本地的不一样,我需要这样才能运行:
./gradlew clean build && java -jar build/libs/actuator-service-0.0.1-SNAPSHOT.jar
。
现在,该服务从端口 9000 启动。
我们可以通过在终端中运行以下命令来测试它是否在端口 9000 上运行:
$ curl localhost:8080/hello-world
curl: (52) Empty reply from server
$ curl localhost:9000/hello-world
{"id":1,"content":"Hello, Stranger!"}
$ curl localhost:9001/actuator/health
{"status":"UP"}
测试应用
要检查我们的应用是否正常工作,我们应该为应用编写单元测试和集成测试。src/test/java/com/example/actuatorservice/HelloWorldApplicationTests.java
中的测试类可以确保:
- 我们的控制器反应灵敏;
- 我们的管理端点是响应式的。
请注意,测试会在随机端口上启动应用。以下清单显示了测试类:
/*
* Copyright 2012-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.actuatorservice;
import java.util.Map;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.TestPropertySource;
import static org.assertj.core.api.BDDAssertions.then;
/**
* Basic integration tests for service demo application.
*
* @author Dave Syer
*/
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestPropertySource(properties = {"management.port=0"})
public class HelloWorldApplicationTests {
@LocalServerPort
private int port;
@Value("${local.management.port}")
private int mgt;
@Autowired
private TestRestTemplate testRestTemplate;
@Test
public void shouldReturn200WhenSendingRequestToController() throws Exception {
@SuppressWarnings("rawtypes")
ResponseEntity<Map> entity = this.testRestTemplate.getForEntity(
"http://localhost:" + this.port + "/hello-world", Map.class);
then(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
}
@Test
public void shouldReturn200WhenSendingRequestToManagementEndpoint() throws Exception {
@SuppressWarnings("rawtypes")
ResponseEntity<Map> entity = this.testRestTemplate.getForEntity(
"http://localhost:" + this.mgt + "/actuator/info", Map.class);
then(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
}
}
概述
Congratulations! We just use Spring to develop a simple RESTful service, and use Spring Boot Actuator added some useful built-in service.
See also
The following guidelines may be helpful:
- Build applications using Spring Boot (please do look forward ~)
- Web services using Spring MVC content (please do look forward ~)
Want to see other content guidelines? Please visit this guide belongs to column: " the Spring Official Guide "