提交 284806f3 编写于 作者: 茶陵後's avatar 茶陵後 👍

#1 structure 分支中也删除en目录

上级 6e53783e
# Spring 中文文档社区
从实操的角度整理翻译`Spring`相关文档,包括`快速开始``安装指南``开发工具配置``代码案例`等。
## 内容大纲
- 概述
- 快速开始
- 系统要求
- 安装指南
- 脚手架
- VSCode
- IntelliJ IDEA
- 开发你的第一个 Spring Boot 应用程序
- 构建 RESTful Web 服务
- 使用 RESTful Web 服务
## 参与贡献
所有 **`Java Spring 熟练使用者`** 可以参与到`Spring 中文文档社区`的建设中来,选择自己感兴趣题目,可以直接撰写文章,也可以翻译 [Spring 官方](https://spring.io/) 上面的内容,也可以校对别人翻译的文章。具体贡献流程如下。
![](https://gitcode.net/zkxw2008/my-material/-/raw/master/spring/readme-1.png)
1、Fork[此仓库](https://gitcode.net/dev-cloud/spring)到自己的[GitCode](https://gitcode.net/)账户下。
2、查看[Issue](https://gitcode.net/dev-cloud/spring/-/issues) 确定自己需要完成的题目。
3、对于已有中文的文档内容文件,可以执行校对。
4、对于暂时无中文文档内容的,可以直接贡献(翻译/撰写)原创中文文档。
5、内容完成者向[此仓库](https://gitcode.net/dev-cloud/spring)提交 PR(Pull Request)。
6、[此仓库](https://gitcode.net/dev-cloud/spring)审核人员审核通过,符合要求的,即会 Merge 到[此仓库](https://gitcode.net/dev-cloud/spring)中。
7、被 Merged 的 PR,会得到 200 ~ 500元不等的奖励。
# Consuming a RESTful Web Service
This guide walks you through the process of creating an application that consumes a RESTful web service.
## What You Will Build
You will build an application that uses Spring’s `RestTemplate` to retrieve a random Spring Boot quotation at https://quoters.apps.pcfone.io/api/random.
## What You Need
- About 15 minutes
- A favorite text editor or IDE
- [JDK 1.8](http://www.oracle.com/technetwork/java/javase/downloads/index.html) or later
- [Gradle 4+](http://www.gradle.org/downloads) or [Maven 3.2+](https://maven.apache.org/download.cgi)
- You can also import the code straight into your IDE:
- [Spring Tool Suite (STS)](https://spring.io/guides/gs/sts)
- [IntelliJ IDEA](https://spring.io/guides/gs/intellij-idea/)
## How to complete this guide
Like most Spring [Getting Started guides](https://spring.io/guides), you can start from scratch and complete each step or you can bypass basic setup steps that are already familiar to you. Either way, you end up with working code.
To **start from scratch**, move on to [Starting with Spring Initializr](https://spring.io/guides/gs/consuming-rest/#scratch).
To **skip the basics**, do the following:
- [Download](https://github.com/spring-guides/gs-consuming-rest/archive/main.zip) and unzip the source repository for this guide, or clone it using [Git](https://spring.io/understanding/Git): `git clone https://github.com/spring-guides/gs-consuming-rest.git`
- cd into `gs-consuming-rest/initial`
- Jump ahead to [Fetching a REST Resource](https://spring.io/guides/gs/consuming-rest/#initial).
**When you finish**, you can check your results against the code in `gs-consuming-rest/complete`.
## Starting with Spring Initializr
You can use this [pre-initialized project](https://start.spring.io/#!type=maven-project&language=java&platformVersion=2.5.5&packaging=jar&jvmVersion=11&groupId=com.example&artifactId=consuming-rest&name=consuming-rest&description=Demo project for Spring Boot&packageName=com.example.consuming-rest&dependencies=web) and click Generate to download a ZIP file. This project is configured to fit the examples in this tutorial.
To manually initialize the project:
1. Navigate to [https://start.spring.io](https://start.spring.io/). This service pulls in all the dependencies you need for an application and does most of the setup for you.
2. Choose either Gradle or Maven and the language you want to use. This guide assumes that you chose Java.
3. Click **Dependencies** and select **Spring Web**.
4. Click **Generate**.
5. Download the resulting ZIP file, which is an archive of a web application that is configured with your choices.
If your IDE has the Spring Initializr integration, you can complete this process from your IDE.
You can also fork the project from Github and open it in your IDE or other editor.
## Fetching a REST Resource
With project setup complete, you can create a simple application that consumes a RESTful service.
A RESTful service has been stood up at https://quoters.apps.pcfone.io/api/random. It randomly fetches quotations about Spring Boot and returns them as JSON documents.
If you request that URL through a web browser or curl, you receive a JSON document that looks something like this:
```
{
type: "success",
value: {
id: 10,
quote: "Really loving Spring Boot, makes stand alone Spring apps easy."
}
}
```
That is easy enough but not terribly useful when fetched through a browser or through curl.
A more useful way to consume a REST web service is programmatically. To help you with that task, Spring provides a convenient template class called [`RestTemplate`](https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html). `RestTemplate` makes interacting with most RESTful services a one-line incantation. And it can even bind that data to custom domain types.
First, you need to create a domain class to contain the data that you need. The following listing shows the `Quote` class, which you can use as your domain class:
```
src/main/java/com/example/consumingrest/Quote.java
```
```
package com.example.consumingrest;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@JsonIgnoreProperties(ignoreUnknown = true)
public class Quote {
private String type;
private Value value;
public Quote() {
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Value getValue() {
return value;
}
public void setValue(Value value) {
this.value = value;
}
@Override
public String toString() {
return "Quote{" +
"type='" + type + '\'' +
", value=" + value +
'}';
}
}
```
This simple Java class has a handful of properties and matching getter methods. It is annotated with `@JsonIgnoreProperties` from the Jackson JSON processing library to indicate that any properties not bound in this type should be ignored.
To directly bind your data to your custom types, you need to specify the variable name to be exactly the same as the key in the JSON document returned from the API. In case your variable name and key in JSON doc do not match, you can use `@JsonProperty` annotation to specify the exact key of the JSON document. (This example matches each variable name to a JSON key, so you do not need that annotation here.)
You also need an additional class, to embed the inner quotation itself. The `Value` class fills that need and is shown in the following listing (at `src/main/java/com/example/consumingrest/Value.java`):
```
package com.example.consumingrest;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@JsonIgnoreProperties(ignoreUnknown = true)
public class Value {
private Long id;
private String quote;
public Value() {
}
public Long getId() {
return this.id;
}
public String getQuote() {
return this.quote;
}
public void setId(Long id) {
this.id = id;
}
public void setQuote(String quote) {
this.quote = quote;
}
@Override
public String toString() {
return "Value{" +
"id=" + id +
", quote='" + quote + '\'' +
'}';
}
}
```
This uses the same annotations but maps onto other data fields.
## Finishing the Application
The Initalizr creates a class with a `main()` method. The following listing shows the class the Initializr creates (at `src/main/java/com/example/consumingrest/ConsumingRestApplication.java`):
```
package com.example.consumingrest;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ConsumingRestApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumingRestApplication.class, args);
}
}
```
Now you need to add a few other things to the `ConsumingRestApplication` class to get it to show quotations from our RESTful source. You need to add:
- A logger, to send output to the log (the console, in this example).
- A `RestTemplate`, which uses the Jackson JSON processing library to process the incoming data.
- A `CommandLineRunner` that runs the `RestTemplate` (and, consequently, fetches our quotation) on startup.
The following listing shows the finished `ConsumingRestApplication` class (at `src/main/java/com/example/consumingrest/ConsumingRestApplication.java`):
```
package com.example.consumingrest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
public class ConsumingRestApplication {
private static final Logger log = LoggerFactory.getLogger(ConsumingRestApplication.class);
public static void main(String[] args) {
SpringApplication.run(ConsumingRestApplication.class, args);
}
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.build();
}
@Bean
public CommandLineRunner run(RestTemplate restTemplate) throws Exception {
return args -> {
Quote quote = restTemplate.getForObject(
"https://quoters.apps.pcfone.io/api/random", Quote.class);
log.info(quote.toString());
};
}
}
```
## Running the Application
You can run the application from the command line with Gradle or Maven. You can also build a single executable JAR file that contains all the necessary dependencies, classes, and resources and run that. Building an executable jar makes it easy to ship, version, and deploy the service as an application throughout the development lifecycle, across different environments, and so forth.
If you use Gradle, you can run the application by using `./gradlew bootRun`. Alternatively, you can build the JAR file by using `./gradlew build` and then run the JAR file, as follows:
```
java -jar build/libs/gs-consuming-rest-0.1.0.jar
```
If you use Maven, you can run the application by using `./mvnw spring-boot:run`. Alternatively, you can build the JAR file with `./mvnw clean package` and then run the JAR file, as follows:
```
java -jar target/gs-consuming-rest-0.1.0.jar
```
The steps described here create a runnable JAR. You can also build a classic WAR file.
You should see output similar to the following but with a random quotation:
```
2019-08-22 14:06:46.506 INFO 42940 --- [ main] c.e.c.ConsumingRestApplication : Quote{type='success', value=Value{id=1, quote='Working with Spring Boot is like pair-programming with the Spring developers.'}}
```
If you see an error that reads, `Could not extract response: no suitable HttpMessageConverter found for response type [class com.example.consumingrest.Quote]`, it is possible that you are in an environment that cannot connect to the backend service (which sends JSON if you can reach it). Maybe you are behind a corporate proxy. Try setting the `http.proxyHost` and `http.proxyPort` system properties to values appropriate for your environment.
## Summary
Congratulations! You have just developed a simple REST client by using Spring Boot.
原文链接: https://spring.io/guides/gs/consuming-rest/
## Developing Your First Spring Boot Application
This section describes how to develop a small “Hello World!” web application that highlights some of Spring Boot’s key features. We use Maven to build this project, since most IDEs support it.
Tip:
The [spring.io](https://spring.io/) web site contains many “Getting Started” [guides](https://spring.io/guides) that use Spring Boot. If you need to solve a specific problem, check there first.
You can shortcut the steps below by going to [start.spring.io](https://start.spring.io/) and choosing the "Web" starter from the dependencies searcher. Doing so generates a new project structure so that you can [start coding right away](https://docs.spring.io/spring-boot/docs/2.6.4/reference/html/getting-started.html#getting-started.first-application.code). Check the [start.spring.io user guide](https://github.com/spring-io/start.spring.io/blob/main/USING.adoc) for more details.
Before we begin, open a terminal and run the following commands to ensure that you have valid versions of Java and Maven installed:
```
$ java -version
java version "1.8.0_102"
Java(TM) SE Runtime Environment (build 1.8.0_102-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.102-b14, mixed mode)
```
```
$ mvn -v
Apache Maven 3.5.4 (1edded0938998edf8bf061f1ceb3cfdeccf443fe; 2018-06-17T14:33:14-04:00)
Maven home: /usr/local/Cellar/maven/3.3.9/libexec
Java version: 1.8.0_102, vendor: Oracle Corporation
```
Note:
This sample needs to be created in its own directory. Subsequent instructions assume that you have created a suitable directory and that it is your current directory.
### Creating the POM
We need to start by creating a Maven `pom.xml` file. The `pom.xml` is the recipe that is used to build your project. Open your favorite text editor and add the following:
```xml
<?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>
<groupId>com.example</groupId>
<artifactId>myproject</artifactId>
<version>0.0.1-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.4</version>
</parent>
<!-- Additional lines to be added here... -->
</project>
```
The preceding listing should give you a working build. You can test it by running `mvn package` (for now, you can ignore the “jar will be empty - no content was marked for inclusion!” warning).
Note:
At this point, you could import the project into an IDE (most modern Java IDEs include built-in support for Maven). For simplicity, we continue to use a plain text editor for this example.
### Adding Classpath Dependencies
Spring Boot provides a number of “Starters” that let you add jars to your classpath. Our applications for smoke tests use the `spring-boot-starter-parent` in the `parent` section of the POM. The `spring-boot-starter-parent` is a special starter that provides useful Maven defaults. It also provides a [`dependency-management`](https://docs.spring.io/spring-boot/docs/2.6.4/reference/html/using.html#using.build-systems.dependency-management) section so that you can omit `version` tags for “blessed” dependencies.
Other “Starters” provide dependencies that you are likely to need when developing a specific type of application. Since we are developing a web application, we add a `spring-boot-starter-web` dependency. Before that, we can look at what we currently have by running the following command:
```shell
$ mvn dependency:tree
[INFO] com.example:myproject:jar:0.0.1-SNAPSHOT
```
The `mvn dependency:tree` command prints a tree representation of your project dependencies. You can see that `spring-boot-starter-parent` provides no dependencies by itself. To add the necessary dependencies, edit your `pom.xml` and add the `spring-boot-starter-web` dependency immediately below the `parent` section:
```xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
```
If you run `mvn dependency:tree` again, you see that there are now a number of additional dependencies, including the Tomcat web server and Spring Boot itself.
### Writing the Code
To finish our application, we need to create a single Java file. By default, Maven compiles sources from `src/main/java`, so you need to create that directory structure and then add a file named `src/main/java/MyApplication.java` to contain the following code:
```java
@RestController
@EnableAutoConfiguration
public class MyApplication {
@RequestMapping("/")
String home() {
return "Hello World!";
}
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
```
Although there is not much code here, quite a lot is going on. We step through the important parts in the next few sections.
#### The @RestController and @RequestMapping Annotations
The first annotation on our `MyApplication` class is `@RestController`. This is known as a *stereotype* annotation. It provides hints for people reading the code and for Spring that the class plays a specific role. In this case, our class is a web `@Controller`, so Spring considers it when handling incoming web requests.
The `@RequestMapping` annotation provides “routing” information. It tells Spring that any HTTP request with the `/` path should be mapped to the `home` method. The `@RestController` annotation tells Spring to render the resulting string directly back to the caller.
Tip:
The `@RestController` and `@RequestMapping` annotations are Spring MVC annotations (they are not specific to Spring Boot). See the [MVC section](https://docs.spring.io/spring-framework/docs/5.3.16/reference/html/web.html#mvc) in the Spring Reference Documentation for more details.
#### The @EnableAutoConfiguration Annotation
The second class-level annotation is `@EnableAutoConfiguration`. This annotation tells Spring Boot to “guess” how you want to configure Spring, based on the jar dependencies that you have added. Since `spring-boot-starter-web` added Tomcat and Spring MVC, the auto-configuration assumes that you are developing a web application and sets up Spring accordingly.
```
Starters and Auto-configuration
Auto-configuration is designed to work well with “Starters”, but the two concepts are not directly tied. You are free to pick and choose jar dependencies outside of the starters. Spring Boot still does its best to auto-configure your application.
```
#### The “main” Method
The final part of our application is the `main` method. This is a standard method that follows the Java convention for an application entry point. Our main method delegates to Spring Boot’s `SpringApplication` class by calling `run`. `SpringApplication` bootstraps our application, starting Spring, which, in turn, starts the auto-configured Tomcat web server. We need to pass `MyApplication.class` as an argument to the `run` method to tell `SpringApplication` which is the primary Spring component. The `args` array is also passed through to expose any command-line arguments.
### Running the Example
At this point, your application should work. Since you used the `spring-boot-starter-parent` POM, you have a useful `run` goal that you can use to start the application. Type `mvn spring-boot:run` from the root project directory to start the application. You should see output similar to the following:
```shell
$ mvn spring-boot:run
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.6.4)
....... . . .
....... . . . (log output here)
....... . . .
........ Started MyApplication in 2.222 seconds (JVM running for 6.514)
```
If you open a web browser to `localhost:8080`, you should see the following output:
```
Hello World!
```
To gracefully exit the application, press `ctrl-c`.
### Creating an Executable Jar
We finish our example by creating a completely self-contained executable jar file that we could run in production. Executable jars (sometimes called “fat jars”) are archives containing your compiled classes along with all of the jar dependencies that your code needs to run.
Executable jars and Java
Java does not provide a standard way to load nested jar files (jar files that are themselves contained within a jar). This can be problematic if you are looking to distribute a self-contained application.
To solve this problem, many developers use “uber” jars. An uber jar packages all the classes from all the application’s dependencies into a single archive. The problem with this approach is that it becomes hard to see which libraries are in your application. It can also be problematic if the same filename is used (but with different content) in multiple jars.
Spring Boot takes a [different approach](https://docs.spring.io/spring-boot/docs/2.6.4/reference/html/executable-jar.html#appendix.executable-jar) and lets you actually nest jars directly.
To create an executable jar, we need to add the `spring-boot-maven-plugin` to our `pom.xml`. To do so, insert the following lines just below the `dependencies` section:
```xml
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
```
Note:
The `spring-boot-starter-parent` POM includes `<executions>` configuration to bind the `repackage` goal. If you do not use the parent POM, you need to declare this configuration yourself. See the [plugin documentation](https://docs.spring.io/spring-boot/docs/2.6.4/maven-plugin/reference/htmlsingle/#getting-started) for details.
Save your `pom.xml` and run `mvn package` from the command line, as follows:
```shell
$ mvn package
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building myproject 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] .... ..
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ myproject ---
[INFO] Building jar: /Users/developer/example/spring-boot-example/target/myproject-0.0.1-SNAPSHOT.jar
[INFO]
[INFO] --- spring-boot-maven-plugin:2.6.4:repackage (default) @ myproject ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
```
If you look in the `target` directory, you should see `myproject-0.0.1-SNAPSHOT.jar`. The file should be around 10 MB in size. If you want to peek inside, you can use `jar tvf`, as follows:
```shell
$ jar tvf target/myproject-0.0.1-SNAPSHOT.jar
```
You should also see a much smaller file named `myproject-0.0.1-SNAPSHOT.jar.original` in the `target` directory. This is the original jar file that Maven created before it was repackaged by Spring Boot.
To run that application, use the `java -jar` command, as follows:
```shell
$ java -jar target/myproject-0.0.1-SNAPSHOT.jar
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.6.4)
....... . . .
....... . . . (log output here)
....... . . .
........ Started MyApplication in 2.536 seconds (JVM running for 2.864)
```
As before, to exit the application, press `ctrl-c`.
原文链接: https://docs.spring.io/spring-boot/docs/2.6.4/reference/html/getting-started.html#getting-started.first-application
\ No newline at end of file
# Spring initializr
![2022-03-01-18-11-18](./initializr/2022-03-01-18-11-18.png)
原文链接: https://start.spring.io/
## Installing Spring Boot
Spring Boot can be used with “classic” Java development tools or installed as a command line tool. Either way, you need [Java SDK v1.8](https://www.java.com/) or higher. Before you begin, you should check your current Java installation by using the following command:
```
$ java -version
```
If you are new to Java development or if you want to experiment with Spring Boot, you might want to try the [Spring Boot CLI](https://docs.spring.io/spring-boot/docs/2.6.4/reference/html/getting-started.html#getting-started.installing.cli) (Command Line Interface) first. Otherwise, read on for “classic” installation instructions.
### Installation Instructions for the Java Developer
You can use Spring Boot in the same way as any standard Java library. To do so, include the appropriate `spring-boot-*.jar` files on your classpath. Spring Boot does not require any special tools integration, so you can use any IDE or text editor. Also, there is nothing special about a Spring Boot application, so you can run and debug a Spring Boot application as you would any other Java program.
Although you *could* copy Spring Boot jars, we generally recommend that you use a build tool that supports dependency management (such as Maven or Gradle).
#### Maven Installation
Spring Boot is compatible with Apache Maven 3.3 or above. If you do not already have Maven installed, you can follow the instructions at [maven.apache.org](https://maven.apache.org/).
Tip:
On many operating systems, Maven can be installed with a package manager. If you use OSX Homebrew, try `brew install maven`. Ubuntu users can run `sudo apt-get install maven`. Windows users with [Chocolatey](https://chocolatey.org/) can run `choco install maven` from an elevated (administrator) prompt.
Spring Boot dependencies use the `org.springframework.boot` `groupId`. Typically, your Maven POM file inherits from the `spring-boot-starter-parent` project and declares dependencies to one or more [“Starters”](https://docs.spring.io/spring-boot/docs/2.6.4/reference/html/using.html#using.build-systems.starters). Spring Boot also provides an optional [Maven plugin](https://docs.spring.io/spring-boot/docs/2.6.4/reference/html/build-tool-plugins.html#build-tool-plugins.maven) to create executable jars.
More details on getting started with Spring Boot and Maven can be found in the [Getting Started section](https://docs.spring.io/spring-boot/docs/2.6.4/maven-plugin/reference/htmlsingle/#getting-started) of the Maven plugin’s reference guide.
#### Gradle Installation
Spring Boot is compatible with Gradle 6.8, 6.9, and 7.x. If you do not already have Gradle installed, you can follow the instructions at [gradle.org](https://gradle.org/).
Spring Boot dependencies can be declared by using the `org.springframework.boot` `group`. Typically, your project declares dependencies to one or more [“Starters”](https://docs.spring.io/spring-boot/docs/2.6.4/reference/html/using.html#using.build-systems.starters). Spring Boot provides a useful [Gradle plugin](https://docs.spring.io/spring-boot/docs/2.6.4/reference/html/build-tool-plugins.html#build-tool-plugins.gradle) that can be used to simplify dependency declarations and to create executable jars.
```
Gradle Wrapper
The Gradle Wrapper provides a nice way of “obtaining” Gradle when you need to build a project. It is a small script and library that you commit alongside your code to bootstrap the build process. See docs.gradle.org/current/userguide/gradle_wrapper.html for details.
```
More details on getting started with Spring Boot and Gradle can be found in the [Getting Started section](https://docs.spring.io/spring-boot/docs/2.6.4/gradle-plugin/reference/htmlsingle/#getting-started) of the Gradle plugin’s reference guide.
### Installing the Spring Boot CLI
The Spring Boot CLI (Command Line Interface) is a command line tool that you can use to quickly prototype with Spring. It lets you run [Groovy](https://groovy-lang.org/) scripts, which means that you have a familiar Java-like syntax without so much boilerplate code.
You do not need to use the CLI to work with Spring Boot, but it is a quick way to get a Spring application off the ground without an IDE.
#### Manual Installation
You can download the Spring CLI distribution from the Spring software repository:
- [spring-boot-cli-2.6.4-bin.zip](https://repo.spring.io/release/org/springframework/boot/spring-boot-cli/2.6.4/spring-boot-cli-2.6.4-bin.zip)
- [spring-boot-cli-2.6.4-bin.tar.gz](https://repo.spring.io/release/org/springframework/boot/spring-boot-cli/2.6.4/spring-boot-cli-2.6.4-bin.tar.gz)
Cutting edge [snapshot distributions](https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-cli/) are also available.
Once downloaded, follow the [INSTALL.txt](https://raw.githubusercontent.com/spring-projects/spring-boot/v2.6.4/spring-boot-project/spring-boot-cli/src/main/content/INSTALL.txt) instructions from the unpacked archive. In summary, there is a `spring` script (`spring.bat` for Windows) in a `bin/` directory in the `.zip` file. Alternatively, you can use `java -jar` with the `.jar` file (the script helps you to be sure that the classpath is set correctly).
#### Installation with SDKMAN!
SDKMAN! (The Software Development Kit Manager) can be used for managing multiple versions of various binary SDKs, including Groovy and the Spring Boot CLI. Get SDKMAN! from [sdkman.io](https://sdkman.io/) and install Spring Boot by using the following commands:
```
$ sdk install springboot
$ spring --version
Spring CLI v2.6.4
```
If you develop features for the CLI and want access to the version you built, use the following commands:
```
$ sdk install springboot dev /path/to/spring-boot/spring-boot-cli/target/spring-boot-cli-2.6.4-bin/spring-2.6.4/
$ sdk default springboot dev
$ spring --version
Spring CLI v2.6.4
```
The preceding instructions install a local instance of `spring` called the `dev` instance. It points at your target build location, so every time you rebuild Spring Boot, `spring` is up-to-date.
You can see it by running the following command:
```
$ sdk ls springboot
================================================================================
Available Springboot Versions
================================================================================
> + dev
* 2.6.4
================================================================================
+ - local version
* - installed
> - currently in use
================================================================================
```
#### OSX Homebrew Installation
If you are on a Mac and use [Homebrew](https://brew.sh/), you can install the Spring Boot CLI by using the following commands:
```
$ brew tap spring-io/tap
$ brew install spring-boot
```
Homebrew installs `spring` to `/usr/local/bin`.
Note:
If you do not see the formula, your installation of brew might be out-of-date. In that case, run `brew update` and try again.
#### MacPorts Installation
If you are on a Mac and use [MacPorts](https://www.macports.org/), you can install the Spring Boot CLI by using the following command:
```
$ sudo port install spring-boot-cli
```
#### Command-line Completion
The Spring Boot CLI includes scripts that provide command completion for the [BASH](https://en.wikipedia.org/wiki/Bash_(Unix_shell)) and [zsh](https://en.wikipedia.org/wiki/Z_shell) shells. You can `source` the script (also named `spring`) in any shell or put it in your personal or system-wide bash completion initialization. On a Debian system, the system-wide scripts are in `/shell-completion/bash` and all scripts in that directory are executed when a new shell starts. For example, to run the script manually if you have installed by using SDKMAN!, use the following commands:
```
$ . ~/.sdkman/candidates/springboot/current/shell-completion/bash/spring
$ spring <HIT TAB HERE>
grab help jar run test version
```
Note:
If you install the Spring Boot CLI by using Homebrew or MacPorts, the command-line completion scripts are automatically registered with your shell.
#### Windows Scoop Installation
If you are on a Windows and use [Scoop](https://scoop.sh/), you can install the Spring Boot CLI by using the following commands:
```
> scoop bucket add extras
> scoop install springboot
```
Scoop installs `spring` to `~/scoop/apps/springboot/current/bin`.
Note:
If you do not see the app manifest, your installation of scoop might be out-of-date. In that case, run `scoop update` and try again.
#### Quick-start Spring CLI Example
You can use the following web application to test your installation. To start, create a file called `app.groovy`, as follows:
```
@RestController
class ThisWillActuallyRun {
@RequestMapping("/")
String home() {
"Hello World!"
}
}
```
Then run it from a shell, as follows:
```
$ spring run app.groovy
```
Note:
The first run of your application is slow, as dependencies are downloaded. Subsequent runs are much quicker.
Open `localhost:8080` in your favorite web browser. You should see the following output:
```
Hello World!
```
原文链接: https://docs.spring.io/spring-boot/docs/2.6.4/reference/html/getting-started.html#getting-started.installing
# Working a Getting Started guide with IntelliJ IDEA
This guide walks you through using IntelliJ IDEA to build one of the Getting Started guides.
## What you’ll build
You’ll pick a Spring guide and import it into IntelliJ IDEA. Then you can read the guide, work on the code, and run the project.
## What you’ll need
- About 15 minutes
- [IntelliJ IDEA](https://www.jetbrains.com/idea/download/)
- [JDK 6](http://www.oracle.com/technetwork/java/javase/downloads/index.html) or later
## Installing IntelliJ IDEA
If you don’t have IntelliJ IDEA (Ultimate Edition) installed yet, visit the link up above. From there, you can download a copy for your platform. To install it simply unpack the downloaded archive.
When you’re done, go ahead and launch IntelliJ IDEA.
## Importing a Getting Started guide
To import an existing project you need some code, so clone or copy one of the Getting Started guides, e.g. the [REST Service](https://spring.io/guides/gs/rest-service/) guide:
```
$ git clone https://github.com/spring-guides/gs-rest-service.gitCOPY
```
With IntelliJ IDEA up and running, click **Import Project** on the **Welcome Screen**, or **File | Open** on the main menu:
![spring_guide_welcome_import](./intellij_idea/spring_guide_welcome_import.png)
In the pop-up dialog make sure to select either [Maven](https://spring.io/guides/gs/maven)'s **pom.xml** or [Gradle](https://spring.io/guides/gs/gradle)'s **build.gradle** file under the **complete** folder:
![spring_guide_select_gradle_file](./intellij_idea/spring_guide_select_gradle_file.png)
IntelliJ IDEA will create a project with all the code from the guide ready to run.
## Creating a Project from Scratch
In case you’d like to start with an empty project and copy-and-paste your way through the guide, create a new **Maven** or **Gradle** project in the **Project Wizard**:
![spring_guide_new_project](./intellij_idea/spring_guide_new_project.png)
## See Also
The following guide may also be helpful:
- [Working a Getting Started guide with STS](https://spring.io/guides/gs/sts/)
原文链接: https://spring.io/guides/gs/intellij-idea/
\ No newline at end of file
## Introducing Spring Boot
Spring Boot helps you to create stand-alone, production-grade Spring-based applications that you can run. We take an opinionated view of the Spring platform and third-party libraries, so that you can get started with minimum fuss. Most Spring Boot applications need very little Spring configuration.
You can use Spring Boot to create Java applications that can be started by using `java -jar` or more traditional war deployments. We also provide a command line tool that runs “spring scripts”.
Our primary goals are:
- Provide a radically faster and widely accessible getting-started experience for all Spring development.
- Be opinionated out of the box but get out of the way quickly as requirements start to diverge from the defaults.
- Provide a range of non-functional features that are common to large classes of projects (such as embedded servers, security, metrics, health checks, and externalized configuration).
- Absolutely no code generation and no requirement for XML configuration.
原文链接: https://docs.spring.io/spring-boot/docs/2.6.4/reference/html/getting-started.html#getting-started.introducing-spring-boot
\ No newline at end of file
# Spring Quickstart Guide
## What you'll build
You will build a classic “Hello World!” endpoint which any browser can connect to. You can even tell it your name, and it will respond in a more friendly way.
## What you’ll need
**An Integrated Developer Environment (IDE)**
Popular choices include [IntelliJ IDEA](https://www.jetbrains.com/idea/), [Spring Tools](https://spring.io/tools), [Visual Studio Code](https://code.visualstudio.com/docs/languages/java), or [Eclipse](https://www.eclipse.org/downloads/packages/), and many more.
**A Java™ Development Kit (JDK)**
We recommend [BellSoft Liberica JDK](https://bell-sw.com/) version 8 or version 11.
## Step 1: Start a new Spring Boot project
Use [start.spring.io](https://start.spring.io/) to create a “web” project. In the “Dependencies” dialog search for and add the “web” dependency as shown in the screenshot. Hit the “Generate” button, download the zip, and unpack it into a folder on your computer.
![quick-img-1-12bfde9c5c280b1940d85dee3d81772d](./quickstart_img/quick-img-1-12bfde9c5c280b1940d85dee3d81772d.png)
Projects created by [start.spring.io](https://start.spring.io/) contain [Spring Boot](https://spring.io/projects/spring-boot), a framework that makes Spring ready to work inside your app, but without much code or configuration required. Spring Boot is the quickest and most popular way to start Spring projects.
## Step 2: Add your code
Open up the project in your IDE and locate the `DemoApplication.java` file in the `src/main/java/com/example/demo` folder. Now change the contents of the file by adding the extra method and annotations shown in the code below. You can copy and paste the code or just type it.
```
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@RestController
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@GetMapping("/hello")
public String hello(@RequestParam(value = "name", defaultValue = "World") String name) {
return String.format("Hello %s!", name);
}
}
```
*This is all the code required to create a simple “Hello World” web service in Spring Boot.*
The `hello()` method we’ve added is designed to take a String parameter called `name`, and then combine this parameter with the word `"Hello"` in the code. This means that if you set your name to `“Amy”` in the request, the response would be `“Hello Amy”`.
The `@RestController` annotation tells Spring that this code describes an endpoint that should be made available over the web. The `@GetMapping(“/hello”)` tells Spring to use our `hello()` method to answer requests that get sent to the `http://localhost:8080/hello` address. Finally, the `@RequestParam` is telling Spring to expect a `name` value in the request, but if it’s not there, it will use the word “World” by default.
## Step 3: Try it
Let’s build and run the program. Open a command line (or terminal) and navigate to the folder where you have the project files. We can build and run the application by issuing the following command:
**MacOS/Linux:**
```
./mvnw spring-boot:run
```
**Windows:**
```
mvnw spring-boot:run
```
You should see some output that looks very similar to this:
![quick-img2-ac5ae88c60ffaa062234a580f9f1abc3](./quickstart_img/quick-img2-ac5ae88c60ffaa062234a580f9f1abc3.png)
The last couple of lines here tell us that Spring has started. Spring Boot’s embedded Apache Tomcat server is acting as a webserver and is listening for requests on `localhost` port `8080`. Open your browser and in the address bar at the top enter http://localhost:8080/hello. You should get a nice friendly response like this:
![quick-img3-afa0a1fe446db8e3c8c7a8d9ca532d23](./quickstart_img/quick-img3-afa0a1fe446db8e3c8c7a8d9ca532d23.png)
原文链接: https://spring.io/quickstart
\ No newline at end of file
# Building a RESTful Web Service
This guide walks you through the process of creating a “Hello, World” RESTful web service with Spring.
## What You Will Build
You will build a service that will accept HTTP GET requests at `http://localhost:8080/greeting`.
It will respond with a JSON representation of a greeting, as the following listing shows:
```
{"id":1,"content":"Hello, World!"}
```
You can customize the greeting with an optional `name` parameter in the query string, as the following listing shows:
```
http://localhost:8080/greeting?name=User
```
The `name` parameter value overrides the default value of `World` and is reflected in the response, as the following listing shows:
```
{"id":1,"content":"Hello, User!"}
```
## What You Need
- About 15 minutes
- A favorite text editor or IDE
- [JDK 1.8](http://www.oracle.com/technetwork/java/javase/downloads/index.html) or later
- [Gradle 4+](http://www.gradle.org/downloads) or [Maven 3.2+](https://maven.apache.org/download.cgi)
- You can also import the code straight into your IDE:
- [Spring Tool Suite (STS)](https://spring.io/guides/gs/sts)
- [IntelliJ IDEA](https://spring.io/guides/gs/intellij-idea/)
## How to complete this guide
Like most Spring [Getting Started guides](https://spring.io/guides), you can start from scratch and complete each step or you can bypass basic setup steps that are already familiar to you. Either way, you end up with working code.
To **start from scratch**, move on to [Starting with Spring Initializr](https://spring.io/guides/gs/rest-service/#scratch).
To **skip the basics**, do the following:
- [Download](https://github.com/spring-guides/gs-rest-service/archive/main.zip) and unzip the source repository for this guide, or clone it using [Git](https://spring.io/understanding/Git): `git clone https://github.com/spring-guides/gs-rest-service.git`
- cd into `gs-rest-service/initial`
- Jump ahead to [Create a Resource Representation Class](https://spring.io/guides/gs/rest-service/#initial).
**When you finish**, you can check your results against the code in `gs-rest-service/complete`.
## Starting with Spring Initializr
You can use this [pre-initialized project](https://start.spring.io/#!type=maven-project&language=java&platformVersion=2.5.5&packaging=jar&jvmVersion=11&groupId=com.example&artifactId=rest-service&name=rest-service&description=Demo project for Spring Boot&packageName=com.example.rest-service&dependencies=web) and click Generate to download a ZIP file. This project is configured to fit the examples in this tutorial.
To manually initialize the project:
1. Navigate to [https://start.spring.io](https://start.spring.io/). This service pulls in all the dependencies you need for an application and does most of the setup for you.
2. Choose either Gradle or Maven and the language you want to use. This guide assumes that you chose Java.
3. Click **Dependencies** and select **Spring Web**.
4. Click **Generate**.
5. Download the resulting ZIP file, which is an archive of a web application that is configured with your choices.
```
If your IDE has the Spring Initializr integration, you can complete this process from your IDE.
```
```
You can also fork the project from Github and open it in your IDE or other editor.
```
## Create a Resource Representation Class
Now that you have set up the project and build system, you can create your web service.
Begin the process by thinking about service interactions.
The service will handle `GET` requests for `/greeting`, optionally with a `name` parameter in the query string. The `GET` request should return a `200 OK` response with JSON in the body that represents a greeting. It should resemble the following output:
```
{
"id": 1,
"content": "Hello, World!"
}
```
The `id` field is a unique identifier for the greeting, and `content` is the textual representation of the greeting.
To model the greeting representation, create a resource representation class. To do so, provide a plain old Java object with fields, constructors, and accessors for the `id` and `content` data, as the following listing (from `src/main/java/com/example/restservice/Greeting.java`) shows:
```
package com.example.restservice;
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;
}
}
```
This application uses the [Jackson JSON](https://github.com/FasterXML/jackson) library to automatically marshal instances of type `Greeting` into JSON. Jackson is included by default by the web starter.
## Create a Resource Controller
In Spring’s approach to building RESTful web services, HTTP requests are handled by a controller. These components are identified by the [`@RestController`](https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/RestController.html) annotation, and the `GreetingController` shown in the following listing (from `src/main/java/com/example/restservice/GreetingController.java`) handles `GET` requests for `/greeting` by returning a new instance of the `Greeting` class:
```
package com.example.restservice;
import java.util.concurrent.atomic.AtomicLong;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class GreetingController {
private static final String template = "Hello, %s!";
private final AtomicLong counter = new AtomicLong();
@GetMapping("/greeting")
public Greeting greeting(@RequestParam(value = "name", defaultValue = "World") String name) {
return new Greeting(counter.incrementAndGet(), String.format(template, name));
}
}
```
This controller is concise and simple, but there is plenty going on under the hood. We break it down step by step.
The `@GetMapping` annotation ensures that HTTP GET requests to `/greeting` are mapped to the `greeting()` method.
There are companion annotations for other HTTP verbs (e.g. `@PostMapping` for POST). There is also a `@RequestMapping` annotation that they all derive from, and can serve as a synonym (e.g. `@RequestMapping(method=GET)`).
`@RequestParam` binds the value of the query string parameter `name` into the `name` parameter of the `greeting()` method. If the `name` parameter is absent in the request, the `defaultValue` of `World` is used.
The implementation of the method body creates and returns a new `Greeting` object with `id` and `content` attributes based on the next value from the `counter` and formats the given `name` by using the greeting `template`.
A key difference between a traditional MVC controller and the RESTful web service controller shown earlier is the way that the HTTP response body is created. Rather than relying on a view technology to perform server-side rendering of the greeting data to HTML, this RESTful web service controller populates and returns a `Greeting` object. The object data will be written directly to the HTTP response as JSON.
This code uses Spring [`@RestController`](https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/RestController.html) annotation, which marks the class as a controller where every method returns a domain object instead of a view. It is shorthand for including both `@Controller` and `@ResponseBody`.
The `Greeting` object must be converted to JSON. Thanks to Spring’s HTTP message converter support, you need not do this conversion manually. Because [Jackson 2](https://github.com/FasterXML/jackson) is on the classpath, Spring’s [`MappingJackson2HttpMessageConverter`](https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/http/converter/json/MappingJackson2HttpMessageConverter.html) is automatically chosen to convert the `Greeting` instance to JSON.
`@SpringBootApplication` is a convenience annotation that adds all of the following:
- `@Configuration`: Tags the class as a source of bean definitions for the application context.
- `@EnableAutoConfiguration`: Tells Spring Boot to start adding beans based on classpath settings, other beans, and various property settings. For example, if `spring-webmvc` is on the classpath, this annotation flags the application as a web application and activates key behaviors, such as setting up a `DispatcherServlet`.
- `@ComponentScan`: Tells Spring to look for other components, configurations, and services in the `com/example` package, letting it find the controllers.
The `main()` method uses Spring Boot’s `SpringApplication.run()` method to launch an application. Did you notice that there was not a single line of XML? There is no `web.xml` file, either. This web application is 100% pure Java and you did not have to deal with configuring any plumbing or infrastructure.
### Build an executable JAR
You can run the application from the command line with Gradle or Maven. You can also build a single executable JAR file that contains all the necessary dependencies, classes, and resources and run that. Building an executable jar makes it easy to ship, version, and deploy the service as an application throughout the development lifecycle, across different environments, and so forth.
If you use Gradle, you can run the application by using `./gradlew bootRun`. Alternatively, you can build the JAR file by using `./gradlew build` and then run the JAR file, as follows:
```
java -jar build/libs/gs-rest-service-0.1.0.jar
```
If you use Maven, you can run the application by using `./mvnw spring-boot:run`. Alternatively, you can build the JAR file with `./mvnw clean package` and then run the JAR file, as follows:
```
java -jar target/gs-rest-service-0.1.0.jar
```
The steps described here create a runnable JAR. You can also [build a classic WAR file](https://spring.io/guides/gs/convert-jar-to-war/).
Logging output is displayed. The service should be up and running within a few seconds.
## Test the Service
Now that the service is up, visit `http://localhost:8080/greeting`, where you should see:
```
{"id":1,"content":"Hello, World!"}
```
Provide a `name` query string parameter by visiting `http://localhost:8080/greeting?name=User`. Notice how the value of the `content` attribute changes from `Hello, World!` to `Hello, User!`, as the following listing shows:
```
{"id":2,"content":"Hello, User!"}
```
This change demonstrates that the `@RequestParam` arrangement in `GreetingController` is working as expected. The `name` parameter has been given a default value of `World` but can be explicitly overridden through the query string.
Notice also how the `id` attribute has changed from `1` to `2`. This proves that you are working against the same `GreetingController` instance across multiple requests and that its `counter` field is being incremented on each call as expected.
## Summary
Congratulations! You have just developed a RESTful web service with Spring.
原文链接: https://spring.io/guides/gs/rest-service/
\ No newline at end of file
此差异已折叠。
## Appendix A: List of ItemReaders and ItemWriters
### Item Readers
| Item Reader | Description |
|----------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|AbstractItemCountingItemStreamItemReader| Abstract base class that provides basic<br/>restart capabilities by counting the number of items returned from<br/>an `ItemReader`. |
| AggregateItemReader |An `ItemReader` that delivers a list as its<br/>item, storing up objects from the injected `ItemReader` until they<br/>are ready to be packed out as a collection. This class must be used<br/>as a wrapper for a custom `ItemReader` that can identify the record<br/>boundaries. The custom reader should mark the beginning and end of<br/>records by returning an `AggregateItem` which responds `true` to its<br/>query methods `isHeader()` and `isFooter()`. Note that this reader<br/>is not part of the library of readers provided by Spring Batch<br/>but given as a sample in `spring-batch-samples`.|
| AmqpItemReader | Given a Spring `AmqpTemplate`, it provides<br/>synchronous receive methods. The `receiveAndConvert()` method<br/>lets you receive POJO objects. |
| KafkaItemReader | An `ItemReader` that reads messages from an Apache Kafka topic.<br/>It can be configured to read messages from multiple partitions of the same topic.<br/>This reader stores message offsets in the execution context to support restart capabilities. |
| FlatFileItemReader | Reads from a flat file. Includes `ItemStream`and `Skippable` functionality. See [`FlatFileItemReader`](readersAndWriters.html#flatFileItemReader). |
| HibernateCursorItemReader | Reads from a cursor based on an HQL query. See[`Cursor-based ItemReaders`](readersAndWriters.html#cursorBasedItemReaders). |
| HibernatePagingItemReader | Reads from a paginated HQL query |
| ItemReaderAdapter | Adapts any class to the`ItemReader` interface. |
| JdbcCursorItemReader | Reads from a database cursor via JDBC. See[`Cursor-based ItemReaders`](readersAndWriters.html#cursorBasedItemReaders). |
| JdbcPagingItemReader | Given an SQL statement, pages through the rows,<br/>such that large datasets can be read without running out of<br/>memory. |
| JmsItemReader | Given a Spring `JmsOperations` object and a JMS<br/>Destination or destination name to which to send errors, provides items<br/>received through the injected `JmsOperations#receive()`method. |
| JpaPagingItemReader | Given a JPQL statement, pages through the<br/>rows, such that large datasets can be read without running out of<br/>memory. |
| ListItemReader | Provides the items from a list, one at a<br/>time. |
| MongoItemReader | Given a `MongoOperations` object and a JSON-based MongoDB<br/>query, provides items received from the `MongoOperations#find()` method. |
| Neo4jItemReader | Given a `Neo4jOperations` object and the components of a<br/>Cyhper query, items are returned as the result of the Neo4jOperations.query<br/>method. |
| RepositoryItemReader | Given a Spring Data `PagingAndSortingRepository` object,<br/>a `Sort`, and the name of method to execute, returns items provided by the<br/>Spring Data repository implementation. |
| StoredProcedureItemReader | Reads from a database cursor resulting from the<br/>execution of a database stored procedure. See [`StoredProcedureItemReader`](readersAndWriters.html#StoredProcedureItemReader) |
| StaxEventItemReader | Reads via StAX. see [`StaxEventItemReader`](readersAndWriters.html#StaxEventItemReader). |
| JsonItemReader | Reads items from a Json document. see [`JsonItemReader`](readersAndWriters.html#JsonItemReader). |
### Item Writers
| Item Writer | Description |
|--------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| AbstractItemStreamItemWriter | Abstract base class that combines the`ItemStream` and`ItemWriter` interfaces. |
| AmqpItemWriter | Given a Spring `AmqpTemplate`, it provides<br/>for a synchronous `send` method. The `convertAndSend(Object)`method lets you send POJO objects. |
| CompositeItemWriter | Passes an item to the `write` method of each<br/>in an injected `List` of `ItemWriter` objects. |
| FlatFileItemWriter | Writes to a flat file. Includes `ItemStream` and<br/>Skippable functionality. See [`FlatFileItemWriter`](readersAndWriters.html#flatFileItemWriter). |
| GemfireItemWriter | Using a `GemfireOperations` object, items are either written<br/>or removed from the Gemfire instance based on the configuration of the delete<br/>flag. |
| HibernateItemWriter | This item writer is Hibernate-session aware<br/>and handles some transaction-related work that a non-"hibernate-aware"<br/>item writer would not need to know about and then delegates<br/>to another item writer to do the actual writing. |
| ItemWriterAdapter | Adapts any class to the`ItemWriter` interface. |
| JdbcBatchItemWriter | Uses batching features from a`PreparedStatement`, if available, and can<br/>take rudimentary steps to locate a failure during a`flush`. |
| JmsItemWriter | Using a `JmsOperations` object, items are written<br/>to the default queue through the `JmsOperations#convertAndSend()` method. |
| JpaItemWriter | This item writer is JPA EntityManager-aware<br/>and handles some transaction-related work that a non-"JPA-aware"`ItemWriter` would not need to know about and<br/>then delegates to another writer to do the actual writing. |
| KafkaItemWriter |Using a `KafkaTemplate` object, items are written to the default topic through the`KafkaTemplate#sendDefault(Object, Object)` method using a `Converter` to map the key from the item.<br/>A delete flag can also be configured to send delete events to the topic.|
| MimeMessageItemWriter | Using Spring’s `JavaMailSender`, items of type `MimeMessage`are sent as mail messages. |
| MongoItemWriter | Given a `MongoOperations` object, items are written<br/>through the `MongoOperations.save(Object)` method. The actual write is delayed<br/>until the last possible moment before the transaction commits. |
| Neo4jItemWriter | Given a `Neo4jOperations` object, items are persisted through the`save(Object)` method or deleted through the `delete(Object)` per the`ItemWriter’s` configuration |
|PropertyExtractingDelegatingItemWriter| Extends `AbstractMethodInvokingDelegator`creating arguments on the fly. Arguments are created by retrieving<br/>the values from the fields in the item to be processed (through a`SpringBeanWrapper`), based on an injected array of field<br/>names. |
| RepositoryItemWriter | Given a Spring Data `CrudRepository` implementation,<br/>items are saved through the method specified in the configuration. |
| StaxEventItemWriter | Uses a `Marshaller` implementation to<br/>convert each item to XML and then writes it to an XML file using<br/>StAX. |
| JsonFileItemWriter | Uses a `JsonObjectMarshaller` implementation to<br/>convert each item to Json and then writes it to an Json file.
\ No newline at end of file
此差异已折叠。
此差异已折叠。
# Glossary
## Appendix A: Glossary
### Spring Batch Glossary
Batch
An accumulation of business transactions over time.
Batch Application Style
Term used to designate batch as an application style in its own right, similar to
online, Web, or SOA. It has standard elements of input, validation, transformation of
information to business model, business processing, and output. In addition, it
requires monitoring at a macro level.
Batch Processing
The handling of a batch of many business transactions that have accumulated over a
period of time (such as an hour, a day, a week, a month, or a year). It is the
application of a process or set of processes to many data entities or objects in a
repetitive and predictable fashion with either no manual element or a separate manual
element for error processing.
Batch Window
The time frame within which a batch job must complete. This can be constrained by other
systems coming online, other dependent jobs needing to execute, or other factors
specific to the batch environment.
Step
The main batch task or unit of work. It initializes the business logic and controls the
transaction environment, based on commit interval setting and other factors.
Tasklet
A component created by an application developer to process the business logic for a
Step.
Batch Job Type
Job types describe application of jobs for particular types of processing. Common areas
are interface processing (typically flat files), forms processing (either for online
PDF generation or print formats), and report processing.
Driving Query
A driving query identifies the set of work for a job to do. The job then breaks that
work into individual units of work. For instance, a driving query might be to identify
all financial transactions that have a status of "pending transmission" and send them
to a partner system. The driving query returns a set of record IDs to process. Each
record ID then becomes a unit of work. A driving query may involve a join (if the
criteria for selection falls across two or more tables) or it may work with a single
table.
Item
An item represents the smallest amount of complete data for processing. In the simplest
terms, this might be a line in a file, a row in a database table, or a particular
element in an XML file.
Logical Unit of Work (LUW)
A batch job iterates through a driving query (or other input source, such as a file) to
perform the set of work that the job must accomplish. Each iteration of work performed
is a unit of work.
Commit Interval
A set of LUWs processed within a single transaction.
Partitioning
Splitting a job into multiple threads where each thread is responsible for a subset of
the overall data to be processed. The threads of execution may be within the same JVM
or they may span JVMs in a clustered environment that supports workload balancing.
Staging Table
A table that holds temporary data while it is being processed.
Restartable
A job that can be executed again and assumes the same identity as when run initially.
In other words, it is has the same job instance ID.
Rerunnable
A job that is restartable and manages its own state in terms of the previous run’s
record processing. An example of a rerunnable step is one based on a driving query. If
the driving query can be formed so that it limits the processed rows when the job is
restarted, then it is re-runnable. This is managed by the application logic. Often, a
condition is added to the `where` statement to limit the rows returned by the driving
query with logic resembling "and processedFlag!= true".
Repeat
One of the most basic units of batch processing, it defines by repeatability calling a
portion of code until it is finished and while there is no error. Typically, a batch
process would be repeatable as long as there is input.
Retry
Simplifies the execution of operations with retry semantics most frequently associated
with handling transactional output exceptions. Retry is slightly different from repeat,
rather than continually calling a block of code, retry is stateful and continually
calls the same block of code with the same input, until it either succeeds or some type
of retry limit has been exceeded. It is only generally useful when a subsequent
invocation of the operation might succeed because something in the environment has
improved.
Recover
Recover operations handle an exception in such a way that a repeat process is able to
continue.
Skip
Skip is a recovery strategy often used on file input sources as the strategy for
ignoring bad input records that failed validation.
\ No newline at end of file
此差异已折叠。
此差异已折叠。
# Monitoring and metrics
## Monitoring and metrics
Since version 4.2, Spring Batch provides support for batch monitoring and metrics
based on [Micrometer](https://micrometer.io/). This section describes
which metrics are provided out-of-the-box and how to contribute custom metrics.
### Built-in metrics
Metrics collection does not require any specific configuration. All metrics provided
by the framework are registered in[Micrometer’s global registry](https://micrometer.io/docs/concepts#_global_registry)under the `spring.batch` prefix. The following table explains all the metrics in details:
| *Metric Name* | *Type* | *Description* | *Tags* |
|---------------------------|-----------------|---------------------------|---------------------------------|
| `spring.batch.job` | `TIMER` | Duration of job execution | `name`, `status` |
| `spring.batch.job.active` |`LONG_TASK_TIMER`| Currently active jobs | `name` |
| `spring.batch.step` | `TIMER` |Duration of step execution | `name`, `job.name`, `status` |
| `spring.batch.item.read` | `TIMER` | Duration of item reading |`job.name`, `step.name`, `status`|
|`spring.batch.item.process`| `TIMER` |Duration of item processing|`job.name`, `step.name`, `status`|
|`spring.batch.chunk.write` | `TIMER` | Duration of chunk writing |`job.name`, `step.name`, `status`|
| |The `status` tag can be either `SUCCESS` or `FAILURE`.|
|---|------------------------------------------------------|
### Custom metrics
If you want to use your own metrics in your custom components, we recommend using
Micrometer APIs directly. The following is an example of how to time a `Tasklet`:
```
import io.micrometer.core.instrument.Metrics;
import io.micrometer.core.instrument.Timer;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
public class MyTimedTasklet implements Tasklet {
@Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) {
Timer.Sample sample = Timer.start(Metrics.globalRegistry);
String status = "success";
try {
// do some work
} catch (Exception e) {
// handle exception
status = "failure";
} finally {
sample.stop(Timer.builder("my.tasklet.timer")
.description("Duration of MyTimedTasklet")
.tag("status", status)
.register(Metrics.globalRegistry));
}
return RepeatStatus.FINISHED;
}
}
```
### Disabling metrics
Metrics collection is a concern similar to logging. Disabling logs is typically
done by configuring the logging library and this is no different for metrics.
There is no feature in Spring Batch to disable micrometer’s metrics, this should
be done on micrometer’s side. Since Spring Batch stores metrics in the global
registry of micrometer with the `spring.batch` prefix, it is possible to configure
micrometer to ignore/deny batch metrics with the following snippet:
```
Metrics.globalRegistry.config().meterFilter(MeterFilter.denyNameStartsWith("spring.batch"))
```
Please refer to micrometer’s [reference documentation](http://micrometer.io/docs/concepts#_meter_filters)for more details.
\ No newline at end of file
# Item processing
## Item processing
XMLJavaBoth
The [ItemReader and ItemWriter interfaces](readersAndWriters.html#readersAndWriters) are both very useful for their specific
tasks, but what if you want to insert business logic before writing? One option for both
reading and writing is to use the composite pattern: Create an `ItemWriter` that contains
another `ItemWriter` or an `ItemReader` that contains another `ItemReader`. The following
code shows an example:
```
public class CompositeItemWriter<T> implements ItemWriter<T> {
ItemWriter<T> itemWriter;
public CompositeItemWriter(ItemWriter<T> itemWriter) {
this.itemWriter = itemWriter;
}
public void write(List<? extends T> items) throws Exception {
//Add business logic here
itemWriter.write(items);
}
public void setDelegate(ItemWriter<T> itemWriter){
this.itemWriter = itemWriter;
}
}
```
The preceding class contains another `ItemWriter` to which it delegates after having
provided some business logic. This pattern could easily be used for an `ItemReader` as
well, perhaps to obtain more reference data based upon the input that was provided by the
main `ItemReader`. It is also useful if you need to control the call to `write` yourself.
However, if you only want to 'transform' the item passed in for writing before it is
actually written, you need not `write` yourself. You can just modify the item. For this
scenario, Spring Batch provides the `ItemProcessor` interface, as shown in the following
interface definition:
```
public interface ItemProcessor<I, O> {
O process(I item) throws Exception;
}
```
An `ItemProcessor` is simple. Given one object, transform it and return another. The
provided object may or may not be of the same type. The point is that business logic may
be applied within the process, and it is completely up to the developer to create that
logic. An `ItemProcessor` can be wired directly into a step. For example, assume an`ItemReader` provides a class of type `Foo` and that it needs to be converted to type `Bar`before being written out. The following example shows an `ItemProcessor` that performs
the conversion:
```
public class Foo {}
public class Bar {
public Bar(Foo foo) {}
}
public class FooProcessor implements ItemProcessor<Foo, Bar> {
public Bar process(Foo foo) throws Exception {
//Perform simple transformation, convert a Foo to a Bar
return new Bar(foo);
}
}
public class BarWriter implements ItemWriter<Bar> {
public void write(List<? extends Bar> bars) throws Exception {
//write bars
}
}
```
In the preceding example, there is a class `Foo`, a class `Bar`, and a class`FooProcessor` that adheres to the `ItemProcessor` interface. The transformation is
simple, but any type of transformation could be done here. The `BarWriter` writes `Bar`objects, throwing an exception if any other type is provided. Similarly, the`FooProcessor` throws an exception if anything but a `Foo` is provided. The`FooProcessor` can then be injected into a `Step`, as shown in the following example:
XML Configuration
```
<job id="ioSampleJob">
<step name="step1">
<tasklet>
<chunk reader="fooReader" processor="fooProcessor" writer="barWriter"
commit-interval="2"/>
</tasklet>
</step>
</job>
```
Java Configuration
```
@Bean
public Job ioSampleJob() {
return this.jobBuilderFactory.get("ioSampleJob")
.start(step1())
.build();
}
@Bean
public Step step1() {
return this.stepBuilderFactory.get("step1")
.<Foo, Bar>chunk(2)
.reader(fooReader())
.processor(fooProcessor())
.writer(barWriter())
.build();
}
```
A difference between `ItemProcessor` and `ItemReader` or `ItemWriter` is that an `ItemProcessor`is optional for a `Step`.
### Chaining ItemProcessors
Performing a single transformation is useful in many scenarios, but what if you want to
'chain' together multiple `ItemProcessor` implementations? This can be accomplished using
the composite pattern mentioned previously. To update the previous, single
transformation, example, `Foo` is transformed to `Bar`, which is transformed to `Foobar`and written out, as shown in the following example:
```
public class Foo {}
public class Bar {
public Bar(Foo foo) {}
}
public class Foobar {
public Foobar(Bar bar) {}
}
public class FooProcessor implements ItemProcessor<Foo, Bar> {
public Bar process(Foo foo) throws Exception {
//Perform simple transformation, convert a Foo to a Bar
return new Bar(foo);
}
}
public class BarProcessor implements ItemProcessor<Bar, Foobar> {
public Foobar process(Bar bar) throws Exception {
return new Foobar(bar);
}
}
public class FoobarWriter implements ItemWriter<Foobar>{
public void write(List<? extends Foobar> items) throws Exception {
//write items
}
}
```
A `FooProcessor` and a `BarProcessor` can be 'chained' together to give the resultant`Foobar`, as shown in the following example:
```
CompositeItemProcessor<Foo,Foobar> compositeProcessor =
new CompositeItemProcessor<Foo,Foobar>();
List itemProcessors = new ArrayList();
itemProcessors.add(new FooProcessor());
itemProcessors.add(new BarProcessor());
compositeProcessor.setDelegates(itemProcessors);
```
Just as with the previous example, the composite processor can be configured into the`Step`:
XML Configuration
```
<job id="ioSampleJob">
<step name="step1">
<tasklet>
<chunk reader="fooReader" processor="compositeItemProcessor" writer="foobarWriter"
commit-interval="2"/>
</tasklet>
</step>
</job>
<bean id="compositeItemProcessor"
class="org.springframework.batch.item.support.CompositeItemProcessor">
<property name="delegates">
<list>
<bean class="..FooProcessor" />
<bean class="..BarProcessor" />
</list>
</property>
</bean>
```
Java Configuration
```
@Bean
public Job ioSampleJob() {
return this.jobBuilderFactory.get("ioSampleJob")
.start(step1())
.build();
}
@Bean
public Step step1() {
return this.stepBuilderFactory.get("step1")
.<Foo, Foobar>chunk(2)
.reader(fooReader())
.processor(compositeProcessor())
.writer(foobarWriter())
.build();
}
@Bean
public CompositeItemProcessor compositeProcessor() {
List<ItemProcessor> delegates = new ArrayList<>(2);
delegates.add(new FooProcessor());
delegates.add(new BarProcessor());
CompositeItemProcessor processor = new CompositeItemProcessor();
processor.setDelegates(delegates);
return processor;
}
```
### Filtering Records
One typical use for an item processor is to filter out records before they are passed to
the `ItemWriter`. Filtering is an action distinct from skipping. Skipping indicates that
a record is invalid, while filtering simply indicates that a record should not be
written.
For example, consider a batch job that reads a file containing three different types of
records: records to insert, records to update, and records to delete. If record deletion
is not supported by the system, then we would not want to send any "delete" records to
the `ItemWriter`. But, since these records are not actually bad records, we would want to
filter them out rather than skip them. As a result, the `ItemWriter` would receive only
"insert" and "update" records.
To filter a record, you can return `null` from the `ItemProcessor`. The framework detects
that the result is `null` and avoids adding that item to the list of records delivered to
the `ItemWriter`. As usual, an exception thrown from the `ItemProcessor` results in a
skip.
### Validating Input
In the [ItemReaders and ItemWriters](readersAndWriters.html#readersAndWriters) chapter, multiple approaches to parsing input have been
discussed. Each major implementation throws an exception if it is not 'well-formed'. The`FixedLengthTokenizer` throws an exception if a range of data is missing. Similarly,
attempting to access an index in a `RowMapper` or `FieldSetMapper` that does not exist or
is in a different format than the one expected causes an exception to be thrown. All of
these types of exceptions are thrown before `read` returns. However, they do not address
the issue of whether or not the returned item is valid. For example, if one of the fields
is an age, it obviously cannot be negative. It may parse correctly, because it exists and
is a number, but it does not cause an exception. Since there are already a plethora of
validation frameworks, Spring Batch does not attempt to provide yet another. Rather, it
provides a simple interface, called `Validator`, that can be implemented by any number of
frameworks, as shown in the following interface definition:
```
public interface Validator<T> {
void validate(T value) throws ValidationException;
}
```
The contract is that the `validate` method throws an exception if the object is invalid
and returns normally if it is valid. Spring Batch provides an out of the box`ValidatingItemProcessor`, as shown in the following bean definition:
XML Configuration
```
<bean class="org.springframework.batch.item.validator.ValidatingItemProcessor">
<property name="validator" ref="validator" />
</bean>
<bean id="validator" class="org.springframework.batch.item.validator.SpringValidator">
<property name="validator">
<bean class="org.springframework.batch.sample.domain.trade.internal.validator.TradeValidator"/>
</property>
</bean>
```
Java Configuration
```
@Bean
public ValidatingItemProcessor itemProcessor() {
ValidatingItemProcessor processor = new ValidatingItemProcessor();
processor.setValidator(validator());
return processor;
}
@Bean
public SpringValidator validator() {
SpringValidator validator = new SpringValidator();
validator.setValidator(new TradeValidator());
return validator;
}
```
You can also use the `BeanValidatingItemProcessor` to validate items annotated with
the Bean Validation API (JSR-303) annotations. For example, given the following type `Person`:
```
class Person {
@NotEmpty
private String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
```
you can validate items by declaring a `BeanValidatingItemProcessor` bean in your
application context and register it as a processor in your chunk-oriented step:
```
@Bean
public BeanValidatingItemProcessor<Person> beanValidatingItemProcessor() throws Exception {
BeanValidatingItemProcessor<Person> beanValidatingItemProcessor = new BeanValidatingItemProcessor<>();
beanValidatingItemProcessor.setFilter(true);
return beanValidatingItemProcessor;
}
```
### Fault Tolerance
When a chunk is rolled back, items that have been cached during reading may be
reprocessed. If a step is configured to be fault tolerant (typically by using skip or
retry processing), any `ItemProcessor` used should be implemented in a way that is
idempotent. Typically that would consist of performing no changes on the input item for
the `ItemProcessor` and only updating the
instance that is the result.
\ No newline at end of file
此差异已折叠。
# Repeat
## Repeat
XMLJavaBoth
### RepeatTemplate
Batch processing is about repetitive actions, either as a simple optimization or as part
of a job. To strategize and generalize the repetition and to provide what amounts to an
iterator framework, Spring Batch has the `RepeatOperations` interface. The`RepeatOperations` interface has the following definition:
```
public interface RepeatOperations {
RepeatStatus iterate(RepeatCallback callback) throws RepeatException;
}
```
The callback is an interface, shown in the following definition, that lets you insert
some business logic to be repeated:
```
public interface RepeatCallback {
RepeatStatus doInIteration(RepeatContext context) throws Exception;
}
```
The callback is executed repeatedly until the implementation determines that the
iteration should end. The return value in these interfaces is an enumeration that can
either be `RepeatStatus.CONTINUABLE` or `RepeatStatus.FINISHED`. A `RepeatStatus`enumeration conveys information to the caller of the repeat operations about whether
there is any more work to do. Generally speaking, implementations of `RepeatOperations`should inspect the `RepeatStatus` and use it as part of the decision to end the
iteration. Any callback that wishes to signal to the caller that there is no more work to
do can return `RepeatStatus.FINISHED`.
The simplest general purpose implementation of `RepeatOperations` is `RepeatTemplate`, as
shown in the following example:
```
RepeatTemplate template = new RepeatTemplate();
template.setCompletionPolicy(new SimpleCompletionPolicy(2));
template.iterate(new RepeatCallback() {
public RepeatStatus doInIteration(RepeatContext context) {
// Do stuff in batch...
return RepeatStatus.CONTINUABLE;
}
});
```
In the preceding example, we return `RepeatStatus.CONTINUABLE`, to show that there is
more work to do. The callback can also return `RepeatStatus.FINISHED`, to signal to the
caller that there is no more work to do. Some iterations can be terminated by
considerations intrinsic to the work being done in the callback. Others are effectively
infinite loops as far as the callback is concerned and the completion decision is
delegated to an external policy, as in the case shown in the preceding example.
#### RepeatContext
The method parameter for the `RepeatCallback` is a `RepeatContext`. Many callbacks ignore
the context. However, if necessary, it can be used as an attribute bag to store transient
data for the duration of the iteration. After the `iterate` method returns, the context
no longer exists.
If there is a nested iteration in progress, a `RepeatContext` has a parent context. The
parent context is occasionally useful for storing data that need to be shared between
calls to `iterate`. This is the case, for instance, if you want to count the number of
occurrences of an event in the iteration and remember it across subsequent calls.
#### RepeatStatus
`RepeatStatus` is an enumeration used by Spring Batch to indicate whether processing has
finished. It has two possible `RepeatStatus` values, described in the following table:
| *Value* | *Description* |
|-----------|--------------------------------------|
|CONTINUABLE| There is more work to do. |
| FINISHED |No more repetitions should take place.|
`RepeatStatus` values can also be combined with a logical AND operation by using the`and()` method in `RepeatStatus`. The effect of this is to do a logical AND on the
continuable flag. In other words, if either status is `FINISHED`, then the result is`FINISHED`.
### Completion Policies
Inside a `RepeatTemplate`, the termination of the loop in the `iterate` method is
determined by a `CompletionPolicy`, which is also a factory for the `RepeatContext`. The`RepeatTemplate` has the responsibility to use the current policy to create a`RepeatContext` and pass that in to the `RepeatCallback` at every stage in the iteration.
After a callback completes its `doInIteration`, the `RepeatTemplate` has to make a call
to the `CompletionPolicy` to ask it to update its state (which will be stored in the`RepeatContext`). Then it asks the policy if the iteration is complete.
Spring Batch provides some simple general purpose implementations of `CompletionPolicy`.`SimpleCompletionPolicy` allows execution up to a fixed number of times (with`RepeatStatus.FINISHED` forcing early completion at any time).
Users might need to implement their own completion policies for more complicated
decisions. For example, a batch processing window that prevents batch jobs from executing
once the online systems are in use would require a custom policy.
### Exception Handling
If there is an exception thrown inside a `RepeatCallback`, the `RepeatTemplate` consults
an `ExceptionHandler`, which can decide whether or not to re-throw the exception.
The following listing shows the `ExceptionHandler` interface definition:
```
public interface ExceptionHandler {
void handleException(RepeatContext context, Throwable throwable)
throws Throwable;
}
```
A common use case is to count the number of exceptions of a given type and fail when a
limit is reached. For this purpose, Spring Batch provides the`SimpleLimitExceptionHandler` and a slightly more flexible`RethrowOnThresholdExceptionHandler`. The `SimpleLimitExceptionHandler` has a limit
property and an exception type that should be compared with the current exception. All
subclasses of the provided type are also counted. Exceptions of the given type are
ignored until the limit is reached, and then they are rethrown. Exceptions of other types
are always rethrown.
An important optional property of the `SimpleLimitExceptionHandler` is the boolean flag
called `useParent`. It is `false` by default, so the limit is only accounted for in the
current `RepeatContext`. When set to `true`, the limit is kept across sibling contexts in
a nested iteration (such as a set of chunks inside a step).
### Listeners
Often, it is useful to be able to receive additional callbacks for cross-cutting concerns
across a number of different iterations. For this purpose, Spring Batch provides the`RepeatListener` interface. The `RepeatTemplate` lets users register `RepeatListener`implementations, and they are given callbacks with the `RepeatContext` and `RepeatStatus`where available during the iteration.
The `RepeatListener` interface has the following definition:
```
public interface RepeatListener {
void before(RepeatContext context);
void after(RepeatContext context, RepeatStatus result);
void open(RepeatContext context);
void onError(RepeatContext context, Throwable e);
void close(RepeatContext context);
}
```
The `open` and `close` callbacks come before and after the entire iteration. `before`,`after`, and `onError` apply to the individual `RepeatCallback` calls.
Note that, when there is more than one listener, they are in a list, so there is an
order. In this case, `open` and `before` are called in the same order while `after`,`onError`, and `close` are called in reverse order.
### Parallel Processing
Implementations of `RepeatOperations` are not restricted to executing the callback
sequentially. It is quite important that some implementations are able to execute their
callbacks in parallel. To this end, Spring Batch provides the`TaskExecutorRepeatTemplate`, which uses the Spring `TaskExecutor` strategy to run the`RepeatCallback`. The default is to use a `SynchronousTaskExecutor`, which has the effect
of executing the whole iteration in the same thread (the same as a normal`RepeatTemplate`).
### Declarative Iteration
Sometimes there is some business processing that you know you want to repeat every time
it happens. The classic example of this is the optimization of a message pipeline. It is
more efficient to process a batch of messages, if they are arriving frequently, than to
bear the cost of a separate transaction for every message. Spring Batch provides an AOP
interceptor that wraps a method call in a `RepeatOperations` object for just this
purpose. The `RepeatOperationsInterceptor` executes the intercepted method and repeats
according to the `CompletionPolicy` in the provided `RepeatTemplate`.
The following example shows declarative iteration using the Spring AOP namespace to
repeat a service call to a method called `processMessage` (for more detail on how to
configure AOP interceptors, see the Spring User Guide):
```
<aop:config>
<aop:pointcut id="transactional"
expression="execution(* com..*Service.processMessage(..))" />
<aop:advisor pointcut-ref="transactional"
advice-ref="retryAdvice" order="-1"/>
</aop:config>
<bean id="retryAdvice" class="org.spr...RepeatOperationsInterceptor"/>
```
The following example demonstrates using Java configuration to
repeat a service call to a method called `processMessage` (for more detail on how to
configure AOP interceptors, see the Spring User Guide):
```
@Bean
public MyService myService() {
ProxyFactory factory = new ProxyFactory(RepeatOperations.class.getClassLoader());
factory.setInterfaces(MyService.class);
factory.setTarget(new MyService());
MyService service = (MyService) factory.getProxy();
JdkRegexpMethodPointcut pointcut = new JdkRegexpMethodPointcut();
pointcut.setPatterns(".*processMessage.*");
RepeatOperationsInterceptor interceptor = new RepeatOperationsInterceptor();
((Advised) service).addAdvisor(new DefaultPointcutAdvisor(pointcut, interceptor));
return service;
}
```
The preceding example uses a default `RepeatTemplate` inside the interceptor. To change
the policies, listeners, and other details, you can inject an instance of`RepeatTemplate` into the interceptor.
If the intercepted method returns `void`, then the interceptor always returns`RepeatStatus.CONTINUABLE` (so there is a danger of an infinite loop if the`CompletionPolicy` does not have a finite end point). Otherwise, it returns`RepeatStatus.CONTINUABLE` until the return value from the intercepted method is `null`,
at which point it returns `RepeatStatus.FINISHED`. Consequently, the business logic
inside the target method can signal that there is no more work to do by returning `null`or by throwing an exception that is re-thrown by the `ExceptionHandler` in the provided`RepeatTemplate`.
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
# What’s New in Spring Batch 4.3
## What’s New in Spring Batch 4.3
This release comes with a number of new features, performance improvements,
dependency updates and API deprecations. This section describes the most
important changes. For a complete list of changes, please refer to the[release notes](https://github.com/spring-projects/spring-batch/releases/tag/4.3.0).
### New features
#### New synchronized ItemStreamWriter
Similar to the `SynchronizedItemStreamReader`, this release introduces a`SynchronizedItemStreamWriter`. This feature is useful in multi-threaded steps
where concurrent threads need to be synchronized to not override each other’s writes.
#### New JpaQueryProvider for named queries
This release introduces a new `JpaNamedQueryProvider` next to the`JpaNativeQueryProvider` to ease the configuration of JPA named queries when
using the `JpaPagingItemReader`:
```
JpaPagingItemReader<Foo> reader = new JpaPagingItemReaderBuilder<Foo>()
.name("fooReader")
.queryProvider(new JpaNamedQueryProvider("allFoos", Foo.class))
// set other properties on the reader
.build();
```
#### New JpaCursorItemReader Implementation
JPA 2.2 added the ability to stream results as a cursor instead of only paging.
This release introduces a new JPA item reader that uses this feature to
stream results in a cursor-based fashion similar to the `JdbcCursorItemReader`and `HibernateCursorItemReader`.
#### New JobParametersIncrementer implementation
Similar to the `RunIdIncrementer`, this release adds a new `JobParametersIncrementer`that is based on a `DataFieldMaxValueIncrementer` from Spring Framework.
#### GraalVM Support
This release adds initial support to run Spring Batch applications on GraalVM.
The support is still experimental and will be improved in future releases.
#### Java records Support
This release adds support to use Java records as items in chunk-oriented steps.
The newly added `RecordFieldSetMapper` supports data mapping from flat files to
Java records, as shown in the following example:
```
@Bean
public FlatFileItemReader<Person> itemReader() {
return new FlatFileItemReaderBuilder<Person>()
.name("personReader")
.resource(new FileSystemResource("persons.csv"))
.delimited()
.names("id", "name")
.fieldSetMapper(new RecordFieldSetMapper<>(Person.class))
.build();
}
```
In this example, the `Person` type is a Java record defined as follows:
```
public record Person(int id, String name) { }
```
The `FlatFileItemReader` uses the new `RecordFieldSetMapper` to map data from
the `persons.csv` file to records of type `Person`.
### Performance improvements
#### Use bulk writes in RepositoryItemWriter
Up to version 4.2, in order to use `CrudRepository#saveAll` in `RepositoryItemWriter`,
it was required to extend the writer and override `write(List)`.
In this release, the `RepositoryItemWriter` has been updated to use`CrudRepository#saveAll` by default.
#### Use bulk writes in MongoItemWriter
The `MongoItemWriter` used `MongoOperations#save()` in a for loop
to save items to the database. In this release, this writer has been
updated to use `org.springframework.data.mongodb.core.BulkOperations` instead.
#### Job start/restart time improvement
The implementation of `JobRepository#getStepExecutionCount()` used to load
all job executions and step executions in-memory to do the count on the framework
side. In this release, the implementation has been changed to do a single call to
the database with a SQL count query in order to count step executions.
### Dependency updates
This release updates dependent Spring projects to the following versions:
* Spring Framework 5.3
* Spring Data 2020.0
* Spring Integration 5.4
* Spring AMQP 2.3
* Spring for Apache Kafka 2.6
* Micrometer 1.5
### Deprecations
#### API deprecation
The following is a list of APIs that have been deprecated in this release:
* `org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean`
* `org.springframework.batch.core.explore.support.MapJobExplorerFactoryBean`
* `org.springframework.batch.core.repository.dao.MapJobInstanceDao`
* `org.springframework.batch.core.repository.dao.MapJobExecutionDao`
* `org.springframework.batch.core.repository.dao.MapStepExecutionDao`
* `org.springframework.batch.core.repository.dao.MapExecutionContextDao`
* `org.springframework.batch.item.data.AbstractNeo4jItemReader`
* `org.springframework.batch.item.file.transform.Alignment`
* `org.springframework.batch.item.xml.StaxUtils`
* `org.springframework.batch.core.launch.support.ScheduledJobParametersFactory`
* `org.springframework.batch.item.file.MultiResourceItemReader#getCurrentResource()`
* `org.springframework.batch.core.JobExecution#stop()`
Suggested replacements can be found in the Javadoc of each deprecated API.
#### SQLFire support deprecation
SQLFire has been in [EOL](https://www.vmware.com/latam/products/pivotal-sqlfire.html)since November 1st, 2014. This release deprecates the support of using SQLFire
as a job repository and schedules it for removal in version 5.0.
\ No newline at end of file
# Spring Boot
\ No newline at end of file
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
# Getting Help
If you have trouble with Spring Boot, we would like to help.
* Try the [How-to documents](howto.html#howto).
They provide solutions to the most common questions.
* Learn the Spring basics.
Spring Boot builds on many other Spring projects.
Check the [spring.io](https://spring.io) web-site for a wealth of reference documentation.
If you are starting out with Spring, try one of the [guides](https://spring.io/guides).
* Ask a question.
We monitor [stackoverflow.com](https://stackoverflow.com) for questions tagged with [`spring-boot`](https://stackoverflow.com/tags/spring-boot).
* Report bugs with Spring Boot at [github.com/spring-projects/spring-boot/issues](https://github.com/spring-projects/spring-boot/issues).
Note:
All of Spring Boot is open source, including the documentation. If you find problems with the docs or if you want to improve them, please [get involved](https://github.com/spring-projects/spring-boot/tree/v2.6.4).
\ No newline at end of file
此差异已折叠。
此差异已折叠。
此差异已折叠。
# Legal
Copyright © 2012-2022
Copies of this document may be made for your own use and for distribution to
others, provided that you do not charge any fee for such copies and further
provided that each copy contains this Copyright Notice, whether distributed in
print or electronically.
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
# Spring Cloud
\ No newline at end of file
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
# Spring Data
\ No newline at end of file
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册