10.2.4 Bộ định tuyến (Routers)
Bộ định tuyến (routers), dựa trên một số tiêu chí định tuyến, cho phép phân nhánh trong luồng tích hợp, điều hướng các message đến các kênh khác nhau (xem hình 10.5).

Hình 10.5 Bộ định tuyến điều hướng các message đến các kênh khác nhau, dựa trên một số tiêu chí áp dụng cho các message.
Ví dụ, giả sử bạn có một kênh tên là numberChannel nơi các giá trị số nguyên đi qua. Và giả sử bạn muốn gửi tất cả các message chứa số chẵn đến một kênh tên là evenChannel, trong khi các message chứa số lẻ sẽ được định tuyến đến một kênh tên là oddChannel. Để tạo ra một logic định tuyến như vậy trong luồng tích hợp của bạn, bạn có thể khai báo một bean kiểu AbstractMessageRouter và đánh dấu bean đó với annotation @Router, như sau:
@Bean
@Router(inputChannel="numberChannel")
public AbstractMessageRouter evenOddRouter() {
return new AbstractMessageRouter() {
@Override
protected Collection<MessageChannel>
determineTargetChannels(Message<?> message) {
Integer number = (Integer) message.getPayload();
if (number % 2 == 0) {
return Collections.singleton(evenChannel());
}
return Collections.singleton(oddChannel());
}
};
}
@Bean
public MessageChannel evenChannel() {
return new DirectChannel();
}
@Bean
public MessageChannel oddChannel() {
return new DirectChannel();
}Bean AbstractMessageRouter được khai báo ở đây sẽ nhận các message từ kênh đầu vào tên numberChannel. Việc triển khai được định nghĩa dưới dạng một lớp nội ẩn danh, sẽ kiểm tra payload của message, và nếu đó là số chẵn, nó sẽ trả về kênh tên evenChannel (được khai báo là một bean sau bean router). Ngược lại, nếu payload chứa số lẻ, thì kênh được trả về là oddChannel (cũng được khai báo trong một phương thức bean riêng).
Trong dạng cấu hình Java DSL, các router được khai báo bằng cách gọi route() trong quá trình định nghĩa luồng, như sau:
@Bean
public IntegrationFlow numberRoutingFlow(AtomicInteger source) {
return IntegrationFlows
...
.<Integer, String>route(n -> n%2==0 ? "EVEN":"ODD", mapping -> mapping
.subFlowMapping("EVEN", sf -> sf
.<Integer, Integer>transform(n -> n * 10)
.handle((i,h) -> { ... })
)
.subFlowMapping("ODD", sf -> sf
.transform(RomanNumbers::toRoman)
.handle((i,h) -> { ... })
)
)
.get();
}Mặc dù bạn vẫn có thể khai báo một AbstractMessageRouter và truyền nó vào route(), ví dụ này sử dụng một biểu thức lambda để xác định liệu payload của message là số lẻ hay chẵn. Nếu là số chẵn, một giá trị String là EVEN sẽ được trả về. Nếu là số lẻ, giá trị ODD sẽ được trả về. Những giá trị này sau đó được sử dụng để xác định submapping nào sẽ xử lý message.
