<?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 Blog) 檢索資料、處理資料,然後將其寫入檔案。 本指南使用傳統的 Spring Integration XML 設定。 其他指南展示如何使用 Java 設定和 DSL(包含和不包含 Lambda 運算式)。
您將建立的內容
您將使用傳統 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 檔案,這是使用您的選擇設定的網站應用程式的封存檔。
如果您的 IDE 具有 Spring Initializr 整合,您可以從您的 IDE 完成此程序。 |
您也可以從 Github 分叉專案,並在您的 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 讀取部落格文章。
-
將它們轉換為易於閱讀的
String
,包含文章標題和文章的 URL。 -
將該
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://spring.dev.org.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
,但可以通过属性覆盖。
使應用程式可執行
雖然在較大的應用程式(甚至可能是網站應用程式)中設定 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://spring.dev.org.tw/blog/2014/11/24/spring-integration-java-dsl-1-0-ga-released
This Week in Spring - November 25th, 2014 @ https://spring.dev.org.tw/blog/2014/11/25/this-week-in-spring-november-25th-2014
Spring Integration Java DSL: Line by line tutorial @ https://spring.dev.org.tw/blog/2014/11/25/spring-integration-java-dsl-line-by-line-tutorial
Spring for Apache Hadoop 2.1.0.M2 Released @ https://spring.dev.org.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 提取部落格文章、處理它們並將它們寫入檔案。