Skip to content

Commit e0c5f32

Browse files
committed
Add Java configuration for enricher sample
Introduce Java-based Spring Integration configuration as an alternative to the existing XML configuration. The new EnricherConfiguration class uses `@Configuration` and Integration DSL to define three enricher flows demonstrating different enrichment strategies. The UserGateway interface uses `@MessagingGateway` to provide a simple interface for clients to invoke enricher flows. The application.properties file sets `java-config` as the default profile, allowing users to run the sample with Java configuration out of the box. The Main class now supports profile-based configuration switching to load either Java or XML configuration. Tests have been updated to verify both configuration modes work correctly, with helper methods extracted to reduce code duplication. The XML configuration remains available by explicitly activating the `xml-config` profile, maintaining backward compatibility. All samples can now run using gradlew :enricher:run. Was broken before
1 parent b82882b commit e0c5f32

File tree

4 files changed

+134
-26
lines changed

4 files changed

+134
-26
lines changed

basic/enricher/README.md

Lines changed: 49 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,34 +3,73 @@ Spring Integration - Enricher Sample
33

44
# Overview
55

6-
This sample demonstrates how the Enricher components can be used.
6+
This sample demonstrates how the Content Enricher pattern can be used in Spring Integration. The Content Enricher allows you to augment a message with additional data from an external source without requiring the original sender to know about the enrichment process.
7+
8+
This sample supports both **XML-based** and **Java-based** Spring Integration configurations. You can select which configuration to use by setting the active Spring profile.
9+
10+
## Configuration Options
11+
12+
This sample supports two configuration modes:
13+
14+
* **Java Configuration** (`java-config` profile) - Uses Java `@Configuration` classes from the `config` package. This is the **default** mode.
15+
* **XML Configuration** (`xml-config` profile) - Uses XML configuration files from `META-INF/spring/integration/`
16+
17+
### Profile Selection
18+
19+
Only one configuration profile should be active at a time. The `java-config` and `xml-config` profiles are mutually exclusive.
20+
21+
* If no profile is explicitly provided, `java-config` is used by default (as configured in `application.properties`).
22+
* To use XML configuration, explicitly activate the `xml-config` profile at runtime.
723

824
# Getting Started
925

10-
You can run the sample application by either
26+
## Using Java Configuration (Default)
1127

12-
* running the "Main" class from within STS (Right-click on Main class --> Run As --> Java Application)
13-
* or from the command line execute:
28+
The sample uses Java configuration by default. You can run the sample application by either:
29+
30+
* Running the "Main" class from within your IDE (Right-click on Main class --> Run As --> Java Application)
31+
* Or from the command line execute:
1432

1533
$ gradlew :enricher:run
1634

17-
This example illustrates the usage of the Content Enricher.
35+
In this mode, the application context is defined using Spring Integration Java configuration classes instead of XML. The configuration classes are located in the `org.springframework.integration.samples.enricher.config` package.
36+
37+
## Using XML Configuration
38+
39+
To run the sample with XML configuration, activate the `xml-config` profile:
40+
41+
* From your IDE, set the system property: `-Dspring.profiles.active=xml-config`
42+
* Or from the command line:
43+
44+
$ gradlew :enricher:run -Dspring.profiles.active=xml-config
45+
46+
This mode uses the legacy XML-based wiring from `spring-integration-context.xml`.
47+
48+
# How It Works
49+
50+
This example illustrates the usage of the Content Enricher pattern.
1851

19-
Once the application has started, please execute the various Content Enricher examples by
52+
Once the application has started, please execute the various Content Enricher examples by:
2053

2154
* entering 1 + Enter
2255
* entering 2 + Enter
2356
* entering 3 + Enter
2457

2558
3 different message flows are triggered. For use-cases 1+2 a **User** object containing only the **username** is passed in. For use-case 3 a Map with the **username** key is passed in and enriched with the **User** object using the **user** key:
2659

27-
* 1: In the *Enricher*, pass the full **User** object to the **request channel**.
28-
* 2: In the *Enricher*, pass only the **username** to the **request channel** by using the **request-payload-expression** attribute.
29-
* 3: In the *Enricher*, pass only the username to the **request channel**, executing the same Service Activator as in **2**.
60+
* **1**: In the *Enricher*, pass the full **User** object to the **request channel**.
61+
* **2**: In the *Enricher*, pass only the **username** to the **request channel** by using the **request-payload-expression** attribute.
62+
* **3**: In the *Enricher*, pass only the username to the **request channel**, executing the same Service Activator as in **2**.
63+
64+
## About This Pattern
65+
66+
Spring Integration is moving toward Java configuration as the primary style for new development, while XML configuration remains available for users who prefer that style or are migrating older systems. This sample demonstrates how both approaches can coexist in the same project using Spring profiles to select the desired configuration mode at runtime.
67+
68+
This pattern (Java first, XML as an alternative) is being applied across other samples in this repository, using `basic/barrier` as a reference model.
3069

3170
# Resources
3271

3372
For help please take a look at the Spring Integration documentation:
3473

35-
https://www.springsource.org/spring-integration
74+
https://docs.spring.io/spring-integration/reference/
3675

basic/enricher/src/main/java/org/springframework/integration/samples/enricher/Main.java

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2011-present the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -22,17 +22,27 @@
2222
import org.apache.commons.logging.Log;
2323
import org.apache.commons.logging.LogFactory;
2424

25+
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
2526
import org.springframework.context.support.AbstractApplicationContext;
2627
import org.springframework.context.support.ClassPathXmlApplicationContext;
28+
import org.springframework.core.env.StandardEnvironment;
2729
import org.springframework.integration.samples.enricher.domain.User;
2830
import org.springframework.integration.samples.enricher.service.UserService;
2931

3032

3133
/**
3234
* Starts the Spring Context and will initialize the Spring Integration routes.
35+
* <p>
36+
* This application supports both Java-based and XML-based Spring Integration
37+
* configurations. The configuration mode is selected via Spring profiles:
38+
* <ul>
39+
* <li>java-config (default) - Uses Java configuration classes</li>
40+
* <li>xml-config - Uses XML configuration files</li>
41+
* </ul>
3342
*
3443
* @author Gunnar Hillert
3544
* @author Gary Russell
45+
* @author Glenn Renfro
3646
* @version 1.0
3747
*
3848
*/
@@ -62,8 +72,23 @@ public static void main(final String... args) {
6272
+ EMPTY_LINE
6373
+ LINE_SEPARATOR );
6474

65-
final AbstractApplicationContext context =
66-
new ClassPathXmlApplicationContext("classpath:META-INF/spring/integration/*-context.xml");
75+
// Determine which profile to use
76+
String profile = System.getProperty("spring.profiles.active", "java-config");
77+
78+
final AbstractApplicationContext context;
79+
80+
if ("xml-config".equals(profile)) {
81+
LOGGER.info("\n\n Using XML-based configuration\n\n");
82+
context = new ClassPathXmlApplicationContext("classpath:META-INF/spring/integration/*-context.xml");
83+
} else {
84+
LOGGER.info("\n\n Using Java-based configuration\n\n");
85+
AnnotationConfigApplicationContext annotationContext = new AnnotationConfigApplicationContext();
86+
annotationContext.setEnvironment(new StandardEnvironment());
87+
annotationContext.getEnvironment().setActiveProfiles("java-config");
88+
annotationContext.scan("org.springframework.integration.samples.enricher.config");
89+
annotationContext.refresh();
90+
context = annotationContext;
91+
}
6792

6893
context.registerShutdownHook();
6994

Lines changed: 54 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2010 the original author or authors.
2+
* Copyright 2011-present the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -18,30 +18,71 @@
1818

1919
import org.junit.jupiter.api.Test;
2020

21+
import org.springframework.context.ConfigurableApplicationContext;
22+
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
2123
import org.springframework.context.support.ClassPathXmlApplicationContext;
2224
import org.springframework.integration.samples.enricher.domain.User;
2325

2426
import static org.assertj.core.api.Assertions.assertThat;
2527

2628
/**
27-
* Verify that the Spring Integration Application Context starts successfully.
29+
* Verify that the Spring Integration Application Context starts successfully
30+
* with both Java and XML configurations.
31+
*
32+
* @author Glenn Renfro
2833
*/
2934
public class UserServiceTest {
3035

3136
@Test
32-
public void testStartupOfSpringIntegrationContext() throws Exception {
37+
public void testStartupOfSpringIntegrationContextWithJavaConfig() throws Exception {
38+
AnnotationConfigApplicationContext context = createJavaConfigContext();
39+
Thread.sleep(2000);
40+
context.close();
41+
}
42+
43+
@Test
44+
public void testStartupOfSpringIntegrationContextWithXmlConfig() throws Exception {
3345
final ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
3446
"/META-INF/spring/integration/spring-integration-context.xml", UserServiceTest.class);
3547
Thread.sleep(2000);
3648
context.close();
3749
}
3850

3951
@Test
40-
public void testExecuteFindUser() {
52+
public void testExecuteFindUserWithJavaConfig() {
53+
AnnotationConfigApplicationContext context = createJavaConfigContext();
54+
55+
runFindUserTest(context);
56+
context.close();
57+
}
58+
59+
@Test
60+
public void testExecuteFindUserWithXmlConfig() {
61+
final ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
62+
"/META-INF/spring/integration/spring-integration-context.xml", UserServiceTest.class);
63+
64+
runFindUserTest(context);
65+
context.close();
66+
}
67+
68+
@Test
69+
public void testExecuteFindUserByUsernameWithJavaConfig() {
70+
AnnotationConfigApplicationContext context = createJavaConfigContext();
4171

72+
runFindUserByUsernameTest(context);
73+
context.close();
74+
}
75+
76+
@Test
77+
public void testExecuteFindUserByUsernameWithXmlConfig() {
4278
final ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
4379
"/META-INF/spring/integration/spring-integration-context.xml", UserServiceTest.class);
4480

81+
runFindUserByUsernameTest(context);
82+
context.close();
83+
}
84+
85+
private void runFindUserTest(ConfigurableApplicationContext context) {
4586
final UserService service = context.getBean(UserService.class);
4687

4788
User user = new User("foo", null, null);
@@ -50,15 +91,9 @@ public void testExecuteFindUser() {
5091
assertThat(fullUser.getUsername()).isEqualTo("foo");
5192
assertThat(fullUser.getEmail()).isEqualTo("[email protected]");
5293
assertThat(fullUser.getPassword()).isEqualTo("secret");
53-
context.close();
54-
5594
}
5695

57-
@Test
58-
public void testExecuteFindUserByUsername() {
59-
final ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
60-
"/META-INF/spring/integration/spring-integration-context.xml", UserServiceTest.class);
61-
96+
private void runFindUserByUsernameTest(ConfigurableApplicationContext context) {
6297
final UserService service = context.getBean(UserService.class);
6398

6499
User user = new User("foo", null, null);
@@ -67,8 +102,14 @@ public void testExecuteFindUserByUsername() {
67102
assertThat(fullUser.getUsername()).isEqualTo("foo");
68103
assertThat(fullUser.getEmail()).isEqualTo("[email protected]");
69104
assertThat(fullUser.getPassword()).isEqualTo("secret");
70-
context.close();
71-
72105
}
73106

107+
108+
private AnnotationConfigApplicationContext createJavaConfigContext() {
109+
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
110+
context.getEnvironment().setActiveProfiles("java-config");
111+
context.scan("org.springframework.integration.samples.enricher.config");
112+
context.refresh();
113+
return context;
114+
}
74115
}

build.gradle

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,9 @@ project('enricher') {
532532
api "com.h2database:h2:$h2Version"
533533
api "org.apache.logging.log4j:log4j-core:$log4jVersion"
534534
}
535+
run {
536+
standardInput = System.in
537+
}
535538
}
536539

537540
project('feed') {

0 commit comments

Comments
 (0)