<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.3.0</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>integration-complete</artifactId> <version>0.0.1-SNAPSHOT</version> <name>integration-complete</name> <description>Demo project for Spring Boot</description> <properties> <java.version>17</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-integration</artifactId> </dependency> <dependency> <groupId>org.springframework.integration</groupId> <artifactId>spring-integration-feed</artifactId> </dependency> <dependency> <groupId>org.springframework.integration</groupId> <artifactId>spring-integration-file</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.integration</groupId> <artifactId>spring-integration-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
整合資料
本指南將引導您使用 Spring Integration 建立一個簡單的應用程式,該應用程式從 RSS Feed(Spring 部落格)檢索資料,處理資料,然後將其寫入檔案。本指南使用傳統的 Spring Integration XML 配置。其他指南將展示如何使用帶 Lambda 表示式和不帶 Lambda 表示式的 Java 配置和 DSL。
您將構建什麼
您將使用傳統的 XML 配置透過 Spring Integration 建立一個流程。
您需要什麼
-
大約 15 分鐘
-
喜歡的文字編輯器或 IDE
-
Java 17 或更高版本
-
您也可以將程式碼直接匯入到您的 IDE 中
如何完成本指南
與大多數 Spring 入門指南一樣,您可以從頭開始並完成每個步驟,也可以跳過您已經熟悉的基本設定步驟。無論哪種方式,您最終都會獲得可執行的程式碼。
要從頭開始,請繼續閱讀 使用 Spring Initializr 入門。
要跳過基礎部分,請執行以下操作
-
下載並解壓本指南的原始碼倉庫,或使用 Git 克隆它:
git clone https://github.com/spring-guides/gs-integration.git
-
cd 進入
gs-integration/initial
-
跳到 定義整合流程。
完成後,您可以將結果與 gs-integration/complete
中的程式碼進行對照檢查。
使用 Spring Initializr 入門
您可以使用此預配置專案,然後單擊 Generate 下載 ZIP 檔案。此專案已配置為適合本教程中的示例。
手動初始化專案
-
導航到 https://start.spring.io。此服務會引入應用程式所需的所有依賴項,併為您完成大部分設定工作。
-
選擇 Gradle 或 Maven 以及您想使用的語言。本指南假設您選擇了 Java。
-
單擊 Dependencies(依賴項)並選擇 Spring Integration。
-
單擊 Generate(生成)。
-
下載生成的 ZIP 檔案,它是一個根據您的選擇配置好的 Web 應用程式存檔。
如果您的 IDE 集成了 Spring Initializr,則可以直接在 IDE 中完成此過程。 |
您也可以從 Github Fork 專案並在您的 IDE 或其他編輯器中開啟。 |
新增到構建檔案
對於此示例,您需要新增兩個依賴項
-
spring-integration-feed
-
spring-integration-file
以下列表顯示了最終的 pom.xml
檔案
以下列表顯示了最終的 build.gradle
檔案
plugins { id 'org.springframework.boot' version '3.3.0' id 'java' } apply plugin: 'io.spring.dependency-management' group = 'com.example' version = '0.0.1-SNAPSHOT' sourceCompatibility = '17' repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-integration' implementation 'org.springframework.integration:spring-integration-feed' implementation 'org.springframework.integration:spring-integration-file' testImplementation('org.springframework.boot:spring-boot-starter-test') testImplementation 'org.springframework.integration:spring-integration-test' } test { useJUnitPlatform() }
定義整合流程
對於本指南的示例應用程式,您將定義一個 Spring Integration 流程,該流程:
-
從 spring.io 的 RSS feed 中讀取部落格文章。
-
將它們轉換為包含文章標題和文章 URL 的易讀
String
。 -
將該
String
附加到檔案 (/tmp/si/SpringBlog
) 的末尾。
要定義整合流程,您可以建立一個 Spring XML 配置,其中包含 Spring Integration XML 名稱空間中的少量元素。具體來說,對於所需的整合流程,您將使用這些 Spring Integration 名稱空間中的元素:core、feed 和 file。(獲取後兩者是我們需要修改 Spring Initializr 提供的構建檔案的原因。)
以下 XML 配置檔案(來自 src/main/resources/integration/integration.xml
)定義了整合流程
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:file="http://www.springframework.org/schema/integration/file"
xmlns:feed="http://www.springframework.org/schema/integration/feed"
xsi:schemaLocation="http://www.springframework.org/schema/integration/feed https://www.springframework.org/schema/integration/feed/spring-integration-feed.xsd
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration/file https://www.springframework.org/schema/integration/file/spring-integration-file.xsd
http://www.springframework.org/schema/integration https://www.springframework.org/schema/integration/spring-integration.xsd">
<feed:inbound-channel-adapter id="news" url="https://springframework.tw/blog.atom" auto-startup="${auto.startup:true}">
<int:poller fixed-rate="5000"/>
</feed:inbound-channel-adapter>
<int:transformer
input-channel="news"
expression="payload.title + ' @ ' + payload.link + '#{systemProperties['line.separator']}'"
output-channel="file"/>
<file:outbound-channel-adapter id="file"
mode="APPEND"
charset="UTF-8"
directory="/tmp/si"
filename-generator-expression="'${feed.file.name:SpringBlog}'"/>
</beans>
這裡使用了三個整合元素:
-
<feed:inbound-channel-adapter>
: 一個入站介面卡,每次輪詢檢索一篇文章。此處配置為每五秒輪詢一次。文章被放入名為news
的通道中(對應於介面卡的 ID)。 -
<int:transformer>
: 轉換news
通道中的條目(com.rometools.rome.feed.synd.SyndEntry
),提取條目的標題 (payload.title
) 和連結 (payload.link
),並將它們連線成一個可讀的String
(並新增一個換行符)。該String
然後傳送到名為file
的輸出通道。 -
<file:outbound-channel-adapter>
: 一個出站通道介面卡,將內容從其通道(名為file
)寫入檔案。具體來說,此處配置為將file
通道中的任何內容附加到/tmp/si/SpringBlog
檔案中。
下圖展示了這個簡單的流程

現在忽略 auto-startup
屬性。稍後討論測試時我們將再討論它。現在,請注意它預設為 true
,這意味著應用程式啟動時會獲取文章。還要注意 filename-generator-expression
中的屬性佔位符。這意味著預設值是 SpringBlog
,但可以透過屬性覆蓋。
使應用程式可執行
雖然通常在大型應用程式(甚至可能是 Web 應用程式)中配置 Spring Integration 流程,但沒有理由不能在一個更簡單的獨立應用程式中定義它。這就是您接下來要做的事情:建立一個啟動整合流程並宣告少量 Bean 以支援整合流程的主類。您還將把應用程式構建成一個獨立的、可執行的 JAR 檔案。我們使用 Spring Boot 的 @SpringBootApplication
註解來建立應用程式上下文。由於本指南使用 XML 名稱空間來定義整合流程,因此您必須使用 @ImportResource
註解將其載入到應用程式上下文。以下列表(來自 src/main/java/com/example/integration/IntegrationApplication.java
)顯示了應用程式檔案
package com.example.integration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ImportResource;
@SpringBootApplication
@ImportResource("/integration/integration.xml")
public class IntegrationApplication {
public static void main(String[] args) throws Exception {
ConfigurableApplicationContext ctx = new SpringApplication(IntegrationApplication.class).run(args);
System.out.println("Hit Enter to terminate");
System.in.read();
ctx.close();
}
}
構建可執行 JAR
您可以使用 Gradle 或 Maven 從命令列執行應用程式。您還可以構建一個包含所有必需依賴項、類和資源的單一可執行 JAR 檔案並執行它。構建可執行 JAR 使在整個開發生命週期、跨不同環境中輕鬆交付、版本化和部署服務成為可能。
如果使用 Gradle,可以使用 ./gradlew bootRun
執行應用程式。或者,您可以使用 ./gradlew build
構建 JAR 檔案,然後按如下方式執行 JAR 檔案
如果使用 Maven,可以使用 ./mvnw spring-boot:run
執行應用程式。或者,您可以使用 ./mvnw clean package
構建 JAR 檔案,然後按如下方式執行 JAR 檔案
此處描述的步驟會建立一個可執行的 JAR。您也可以構建一個傳統的 WAR 檔案。 |
執行應用程式
現在您可以透過執行以下命令從 jar 執行應用程式
java -jar build/libs/{project_id}-0.1.0.jar
... app starts up ...
應用程式啟動後,它會連線到 RSS feed 並開始抓取部落格文章。應用程式透過您定義的整合流程處理這些文章,最終將文章資訊附加到 /tmp/si/SpringBlog
檔案中。
應用程式執行一段時間後,您應該能夠在 /tmp/si/SpringBlog
檢視檔案,以檢視一些文章的資料。在基於 UNIX 的作業系統上,您還可以使用 tail
命令檢視寫入檔案時的結果,執行以下命令:
tail -f /tmp/si/SpringBlog
您應該會看到類似於以下示例輸出的內容(實際新聞內容會有所不同)
Spring Integration Java DSL 1.0 GA Released @ https://springframework.tw/blog/2014/11/24/spring-integration-java-dsl-1-0-ga-released
This Week in Spring - November 25th, 2014 @ https://springframework.tw/blog/2014/11/25/this-week-in-spring-november-25th-2014
Spring Integration Java DSL: Line by line tutorial @ https://springframework.tw/blog/2014/11/25/spring-integration-java-dsl-line-by-line-tutorial
Spring for Apache Hadoop 2.1.0.M2 Released @ https://springframework.tw/blog/2014/11/14/spring-for-apache-hadoop-2-1-0-m2-released
測試
檢查 complete
專案,您將看到一個測試用例,位於 src/test/java/com/example/integration/FlowTests.java
package com.example.integration;
import static org.assertj.core.api.Assertions.assertThat;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.integration.endpoint.SourcePollingChannelAdapter;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.messaging.MessageChannel;
import com.rometools.rome.feed.synd.SyndEntryImpl;
@SpringBootTest({ "auto.startup=false", // we don't want to start the real feed
"feed.file.name=Test" }) // use a different file
public class FlowTests {
@Autowired
private SourcePollingChannelAdapter newsAdapter;
@Autowired
private MessageChannel news;
@Test
public void test() throws Exception {
assertThat(this.newsAdapter.isRunning()).isFalse();
SyndEntryImpl syndEntry = new SyndEntryImpl();
syndEntry.setTitle("Test Title");
syndEntry.setLink("http://characters/frodo");
File out = new File("/tmp/si/Test");
out.delete();
assertThat(out.exists()).isFalse();
this.news.send(MessageBuilder.withPayload(syndEntry).build());
assertThat(out.exists()).isTrue();
BufferedReader br = new BufferedReader(new FileReader(out));
String line = br.readLine();
assertThat(line).isEqualTo("Test Title @ http://characters/frodo");
br.close();
out.delete();
}
}
此測試使用 Spring Boot 的測試支援將名為 auto.startup
的屬性設定為 false
。在測試中依賴網路連線通常不是一個好主意,尤其是在 CI 環境中。相反,我們阻止 feed 介面卡啟動,並將一個 SyndEntry
注入到 news
通道中,供流程的其餘部分處理。測試還設定了 feed.file.name
,以便測試寫入不同的檔案。然後它:
-
驗證介面卡已停止。
-
建立一個測試
SyndEntry
。 -
刪除測試輸出檔案(如果存在)。
-
傳送訊息。
-
驗證檔案存在。
-
讀取檔案並驗證資料是否符合預期。
總結
恭喜!您已開發了一個簡單的應用程式,它使用 Spring Integration 從 spring.io 抓取部落格文章,處理它們,並將它們寫入檔案。