diff --git a/spring-integration-reference/src/samples.xml b/spring-integration-reference/src/samples.xml index be9edcc095..0f33f34170 100644 --- a/spring-integration-reference/src/samples.xml +++ b/spring-integration-reference/src/samples.xml @@ -1,6 +1,6 @@ - + Spring Integration Samples
@@ -21,76 +21,89 @@ - The DrinkOrder object may contain multiple Drinks. Once the order + The Order object may contain multiple OrderItems. Once the order is placed, a Splitter will break the composite order message into a single message per drink. Each of these is then processed by a Router that determines whether the drink is hot - or cold (checking the Drink object's 'isIced' property). Finally the + or cold (checking the OrderItem object's 'isIced' property). Finally the Barista prepares each drink, but hot and cold drink preparation are handled by two - distinct methods: 'prepareHotDrink' and 'prepareColdDrink'. + distinct methods: 'prepareHotDrink' and 'prepareColdDrink'. The prepared drinks are then sent to the Waiter where + they are aggregated into a Delivery object. Here is the XML configuration: - + + http://www.springframework.org/schema/integration/stream + http://www.springframework.org/schema/integration/stream/spring-integration-stream-1.0.xsd"> - - + + + - - + - + + + + - + + + + - - - + + + + + + + + + + + + ]]> - Notice that the Message Bus is defined. It will automatically detect and register all channels and endpoints. - The 'annotation-driven' element will enable the detection of the splitter and router - both of which carry - the @MessageEndpoint annotation. That annotation extends Spring's - "stereotype" annotations (by relying on the @Component meta-annotation), and so all classes carrying the - endpoint annotation are capable of being detected by the component-scanner. - split(DrinkOrder order) { - return order.getDrinks(); + public List split(Order order) { + return order.getItems(); } }]]> - MessageChannel + instance (although it can be). As you see in this example, a String-value representing the channel name is + returned instead. + Now turning back to the XML, you see that there are two <service-activator> elements. Each of these - is delegating to the same Barista instance but different methods. The 'barista' could - have been defined in the XML, but instead the @Component annotation is applied: - Barista instance but different methods: 'prepareHotDrink' + or 'prepareColdDrink' corresponding to the two channels where order items have been routed. + - As you can see from the code excerpt above, the barista methods have different delays (the hot - drinks take 5 times as long to prepare). This simulates work being completed at different rates. - When the CafeDemo 'main' method runs, it will loop 100 - times sending a single hot drink and a single cold drink each time. + As you can see from the code excerpt above, the barista methods have different delays (the hot drinks take 5 + times as long to prepare). This simulates work being completed at different rates. When the + CafeDemo 'main' method runs, it will loop 100 times sending a single hot drink and a + single cold drink each time. It actually sends the messages by invoking the 'placeOrder' method on the Cafe + interface. Above, you will see that the <gateway> element is specified in the configuration file. This + triggers the creation of a proxy that implements the given 'service-interface' and connects it to a channel. + The channel name is provided on the @Gateway annotation of the Cafe interface. + public interface Cafe { + + @Gateway(requestChannel="orders") + void placeOrder(Order order); + +} + Finally, have a look at the main() method of the CafeDemo itself. 0) { + if (args.length > 0) { context = new FileSystemXmlApplicationContext(args); } else { context = new ClassPathXmlApplicationContext("cafeDemo.xml", CafeDemo.class); } - context.start(); Cafe cafe = (Cafe) context.getBean("cafe"); - DrinkOrder order = new DrinkOrder(); - Drink hotDoubleLatte = new Drink(DrinkType.LATTE, 2, false); - Drink icedTripleMocha = new Drink(DrinkType.MOCHA, 3, true); - order.addDrink(hotDoubleLatte); - order.addDrink(icedTripleMocha); - for (int i = 0; i < 100; i++) { + for (int i = 1; i <= 100; i++) { + Order order = new Order(i); + order.addItem(DrinkType.LATTE, 2, false); + order.addItem(DrinkType.MOCHA, 3, true); cafe.placeOrder(order); } }]]> @@ -160,25 +191,38 @@ public class Barista { original file so that you can make as many changes as you want and still refer back to the original to compare. - When you run cafeDemo, you will see that all 100 cold drinks are prepared in roughly the same amount of time as - only 20 of the hot drinks. This is to be expected based on their respective delays of 1000 and 5000 milliseconds. - However, by configuring a poller with a concurrent task executor, you can dramatically change the results. For - example, you could use a thread pool executor with 5 workers for the hot drink barista: - + When you run cafeDemo, you will see that the cold drinks are initially prepared more quickly than the hot drinks. + Because there is an aggregator, the cold drinks are effectively limited by the rate of the hot drink preparation. + This is to be expected based on their respective delays of 1000 and 5000 milliseconds. However, by configuring a + poller with a concurrent task executor, you can dramatically change the results. For example, you could use a + thread pool executor with 5 workers for the hot drink barista while keeping the cold drink barista as it is: + - - ]]>]]> + ]]> + + ]]> -]]>]]> +]]>]]> - Also, notice that the worker thread name is displayed with each invocation. You should see that most of - the hot drinks are prepared by the task-executor threads, but that occasionally it throttles the input by - forcing the message-bus (the caller) to invoke the operation. In addition to experimenting with the 'concurrency' - settings, you can also add the 'transactional' sub-element as described in . - If you want to explore the sample in more detail, the source JAR is available in the "src" directory: - 'org.springframework.integration.samples-sources-1.0.0.M6.jar'. + Also, notice that the worker thread name is displayed with each invocation. You will see that the hot drinks are + prepared by the task-executor threads. If you provide a much shorter poller interval (such as 100 milliseconds), + then you will notice that occasionally it throttles the input by forcing the message-bus (the caller) to invoke + the operation. + + + In addition to experimenting with the poller's concurrency settings, you can also add the 'transactional' + sub-element as described in . If you want to explore the sample in more + detail, the source JAR is available in the "src" directory: + 'org.springframework.integration.samples-sources-1.0.0.RC1.jar'.
-
\ No newline at end of file + \ No newline at end of file