Eiws Study Notes
Eiws Study Notes
Study Notes
These study notes were created by Lubos Krnac and are based on various Spring reference documentations.
Spring Framework Reference Documentation 3.2.4.RELEASE copyright notice:
Rod Johnson, Juergen Hoeller, Keith Donald, Colin Sampaleanu, Rob Harrop, Thomas Risberg Alef Arendsen, Darren Davison, Dmitriy Kopylenko, Mark
Pollack, Thierry Templier, Erwin Vervaet, Portia Tung, Ben Hale, Adrian Colyer, John Lewis, Costin Leau, Mark Fisher, Sam Brannen, Ramnivas Laddad,
Arjen Poutsma, Chris Beams, Tareq Abedrabbo, Andy Clement, Dave Syer, Oliver Gierke, Rossen Stoyanchev, Phillip Webb Copyright 2004-2013
Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further
provided that each copy contains this Copyright Notice, whether distributed in print or electronicall
Spring Batch Reference Documentation 2.2.2.RELEASE copyright notice:
Copyright 2005-2013 Lucas Ward, Dave Syer, Thomas Risberg, Robert Kasanicky, Dan Garrette, Wayne Lund, Michael Minella, Chris Schaefer
Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further
provided that each copy contains this Copyright Notice, whether distributed in print or electronically.
Table of Contents
1 Tasks and Scheduling.......................................................................................................................4
1.1 Spring framework provides......................................................................................................4
1.2 TaskExecutor abstraction..........................................................................................................4
1.3 TaskScheduler abstraction........................................................................................................4
1.4 Trigger interface........................................................................................................................5
1.5 Annotation Support...................................................................................................................5
1.6 Task Namespace........................................................................................................................6
1.7 Application Servers...................................................................................................................6
2 Spring Remoting...............................................................................................................................6
2.1 The concepts involved with Spring Remoting on both server- and client-side........................6
2.2 The benefits of Spring Remoting over traditional remoting technologies................................7
2.3 The remoting protocols supported by Spring............................................................................7
2.4 How Spring Remoting-based RMI is less invasive than plain RMI.........................................7
2.5 How client and server interact with each other.........................................................................8
3 Spring Web Services.........................................................................................................................9
3.1 How do Web Services compare to Remoting and Messaging..................................................9
3.2 The approach to building web services that Spring-WS supports............................................9
3.3 The Object-to-XML frameworks supported by Spring-OXM..................................................9
3.4 The strategies supported to map requests to endpoints...........................................................10
3.5 Of these strategies, how does @PayloadRoot work exactly?.................................................11
3.6 The functionality offered by the WebServiceTemplate...........................................................11
3.7 The underlying WS-Security implementations supported by Spring-WS..............................11
3.8 How key stores are supported by Spring-WS for use with WS-Security...............................12
3.9 Additional chapters.................................................................................................................12
3.9.1 Best practises for Spring Web Services...........................................................................12
3.9.2 Error Handling................................................................................................................12
3.9.3 WS testing.......................................................................................................................13
3.9.4 Interceptors......................................................................................................................13
4 RESTful services with Spring-MVC..............................................................................................14
4.1 The main REST principles......................................................................................................14
4.2 Spring MVC is an alternative to JAX-RS, not an implementation.........................................15
4.3 The @RequestMapping annotation, including URI template support....................................16
4.4 The @RequestBody and @ResponseBody annotations.........................................................17
4.5 The functionality offered by the RestTemplate.......................................................................18
5 Spring JMS.....................................................................................................................................19
5.1 Where can Spring-JMS applications obtain their JMS resources from..................................19
5.2 The functionality offered by the JmsTemplate.......................................................................19
1/57
5.3 The functionality offered by Spring's JMS message listener container, including the use of a
MessageListenerAdapter through the 'method' attribute in the <jms:listener/> element..............21
6 Local JMS Transactions with Spring..............................................................................................22
6.1 How to enable local JMS transactions with Spring's message listener container...................22
6.2 If and if so, how is a local JMS transaction made available to the JmsTemplate...................23
6.3 How does Spring attempt to synchronize a local JMS transaction and a local database
transaction......................................................................................................................................23
6.4 The functionality offered by the JmsTransactionManager.....................................................23
7 JTA and Two-phased commit transactions with Spring.................................................................23
7.1 What guarantees does JTA provide that local transactions do not provide.............................23
7.2 How to switch from local to global JTA transactions.............................................................24
7.3 Where can you obtain a JTA transaction manager from.........................................................24
7.4 Additional topics.....................................................................................................................25
7.4.1 Declarative transaction demarcation...............................................................................25
8 Spring Integration...........................................................................................................................26
8.1 Main concepts (Messages, Channels, Endpoint types)...........................................................26
8.1.1 Message...........................................................................................................................26
8.1.2 MessageEndpoint............................................................................................................26
8.1.2.1 Channel Adapter......................................................................................................27
8.1.2.2 Messaging Gateway................................................................................................27
8.1.2.3 Service Activator.....................................................................................................28
8.1.2.4 Message Transformer..............................................................................................28
8.1.2.5 Filter........................................................................................................................29
8.1.2.6 Router......................................................................................................................29
8.1.2.7 Splitter.....................................................................................................................30
8.1.2.8 Aggregator...............................................................................................................30
8.1.3 Error Handling................................................................................................................31
8.1.4 SpEL Expressions...........................................................................................................31
8.2 How to programmatically create new Messages....................................................................31
8.3 Using chains and bridges........................................................................................................32
8.4 The different Channel types and how each of them should be used.......................................33
8.4.1 ChannelInterceptor..........................................................................................................36
8.4.2 Special Channels.............................................................................................................36
8.4.3 Temporary reply channels...............................................................................................36
8.4.4 Point-to-Point Dispatcher................................................................................................37
8.5 The corresponding effects on things like transactions and security.......................................37
8.6 The need for active polling and how to configure that...........................................................37
9 Spring Batch...................................................................................................................................38
9.1 Main concepts (Job, Step, Job Instance, Job Execution, Step Execution, etc.)......................38
9.1.1 Job...................................................................................................................................40
9.1.2 JobInstance......................................................................................................................42
9.1.3 JobLauncher....................................................................................................................42
9.2 The interfaces typically used to implement a chunk-oriented Step........................................43
9.2.1 Step..................................................................................................................................43
9.2.2 Configuring a Step..........................................................................................................43
9.2.3 Inheritance + abstract Step .............................................................................................45
9.2.4 Intercepting Step execution.............................................................................................45
9.2.5 TaskletStep......................................................................................................................46
9.2.6 Controlling Step flow......................................................................................................46
9.2.7 ItemReader......................................................................................................................47
2/57
9.2.8 ItemProcessor..................................................................................................................48
9.2.9 ItemWriter.......................................................................................................................48
9.2.10 Stateful item processing................................................................................................48
9.2.11 ExecutionContextPromotionListener............................................................................48
9.2.12 Late binding of Job and Step attributes.........................................................................49
9.2.13 Implementations of ItemReader and ItemWriter..........................................................50
9.3 How and where state can be stored.........................................................................................50
9.4 What are job parameters and how are they used.....................................................................51
9.5 What is a FieldSetMapper and what is it used for..................................................................51
9.5.1 FieldSet interface............................................................................................................51
9.5.2 FlatFileItemReader..........................................................................................................52
9.5.3 LineTokenizer.................................................................................................................52
9.5.4 FieldSetMapper...............................................................................................................52
9.5.5 DefaultLineMapper.........................................................................................................53
9.5.6 Mapping Fields by Name................................................................................................53
9.5.7 Multiple Record Types within a Single File....................................................................53
9.6 Additional topics.....................................................................................................................54
9.6.1 DB ItemReaders..............................................................................................................54
9.6.2 Repeat..............................................................................................................................55
9.6.3 Scaling and parallel processing.......................................................................................55
3/57
~ created to give other Spring components an abstraction for thread pooling where needed
~ TaskExecutor implementations are used as simple JavaBeans within Spring context
~ out of the box implementations:
SimpleAsyncTaskExecutor
doesn't use thread pool
support concurrency limit will block further invocations until slot is freed up
SyncTaskExecutor
doesn't execute invocation asynchronously (invocation takes place in calling
thread)
ConcurrentTaskExecutor
wrapper for a Java 5 java.util.concurrent.Executor interface
rarely used in comparison to ThreadPoolTaskExecutor
SimpleThreadPoolTaskExecutor
subclass of Quartz's SimpleThreadPool which listens to Spring's lifecycle
callbacks
ThreadPoolTaskExecutor
wrapper for a Java 5 java.util.concurrent.ThreadPoolExecutor
TimerTaskExecutor
uses a single TimerTask.
different from the SyncTaskExecutor - method invocations are executed in a
separate thread, although they are synchronous in that thread
WorkManagerTaskExecutor
convenience class for setting up a CommonJ WorkManager reference in a
Spring context
implements the WorkManager interface and therefore can be used directly as a
WorkManager as well.
4/57
ScheduledFuture
ScheduledFuture
ScheduledFuture
ScheduledFuture
by callers at run-time
methods must be void or return Future type
can't be used in conjunction with lifecycle callbacks (e.g. @PostConstruct)
can have qualifier to override default configured task executor
@Async
Future<String> returnSomething(int i) {
// this will be executed asynchronously
}
2 Spring Remoting
2.1 The concepts involved with Spring Remoting on both server- and
client-side
~ Remoting synchronous calls of remote methods
6/57
2.4 How Spring Remoting-based RMI is less invasive than plain RMI
~ Server side:
exposing POJO services (via RmiServiceExporter)
exposed service interfaces don't have to extend java.rmi.Remote
the binding in the RMI registry is done automatically by Spring
~ Client side:
Spring converts checked exceptions java.rmi.RemoteException into
7/57
<bean class="org.springframework.remoting.rmi.RmiServiceExporter">
<!-- does not necessarily have to be the same name as the bean to be
exported -->
<property name="serviceName" value="AccountService" />
<property name="service" ref="accountService" />
<property name="serviceInterface" value="example.AccountService" />
<!-- defaults to 1099 -->
<property name="registryPort" value="1199" />
</bean>
<bean name="/AccountService"
class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
<property name="service" ref="accountService"/>
<property name="serviceInterface" value="example.AccountService"/>
</bean>
<bean name="accountExporter"
class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
<property name="service" ref="accountService"/>
<property name="serviceInterface" value="example.AccountService"/>
</bean>
8/57
~ Client uses proxy to invoke service functionality (bean from example below can be used
as if it was local bean)
RMI example:
<bean id="accountService"
class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
<property name="serviceUrl" value="rmi://HOST:1199/AccountService" />
<property name="serviceInterface" value="example.AccountService" />
</bean>
<bean id=accountService
class=org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean>
<property name=serviceInterface value=example.AccountService/>
<property name=serviceUrl
value=http://HOST:8080//remoting/AccountService/>
</bean>
Xpath
~ Automatic publishing of generated WSDL
(XWSS) Sun. Prerequisites: Sun JDK / Oracle and the reference implementation of
Sun SAAJ. Requires a security policy file to operate.
Wss4jSecurityInterceptor for integrating Apache WSS4J implements
standards:
SOAP Message Security 1.0 (OASIS)
Username Token Profile 1.0
X.509 Token Profile 1.0
3.8 How key stores are supported by Spring-WS for use with WSSecurity
~ Most cryptographic operations requires a standard java.security.KeyStore. The
keystore stores three types of elements:
1. Private Key: Used by WS-Security to sign and decrypt
2. Symmetric key (or secret key): client and server store the same key. The latter is
used to both encrypt and decrypt.
3. Trust certificates (X509). WS-Security uses to validate certifications, verify the
signature and encryption.
~ KeyStoreFactoryBean can be used to easily load keystores using Spring
configuration. It has two properties:
location to the keystore (eg classphath: truststore.jks or keystore.jks)
password for the keystore.
~ When is security XWSS based, KeyStoreCallbackHandler is needed to handle
various cryptographic callbacks. It has three parameters (exact stores used by the handler
depend on the cryptographic operations that are to be performed by this handler):
keyStore
trustStore
symmetricStore
~ To manage certificates, WSS4J uses a keystore file that is referenced by the
CryptoFactoryBean class.
Contract-first approach
Don't use stubs and skeletons to promote separate evolution of contract and code
Skipping validation (not necessarily good practise)
12/57
soap.server.endpoint.SoapFaultMappingExceptionResolver">
<property name="exceptionMappings">
<value>
java.lang.NumberFormatException=CLIENT, Invalid format
</value>
</property>
</bean>
~ SoapFaultMessageResolver
used on client side by WebServiceTemplate
default implementation for fault response handling
WebServiceTemplate throws SoapFaultClientException exception
wraps received SOAP error message and coverts into SoapFault
can be replaced by custom implementation via property faultMessageResolver
in WebServiceTemplate declaration
3.9.3 WS testing
~ Spring WS provides out of container integration testing with various expectations support
~ Server side
1. Create a MockWebServiceClient instance by calling its factory methods
2. Send request messages by calling sendRequest method (possibly use
RequestCreator callback)
3. Set up response expectations by calling andExpect (possibly use
ResponseMatcher callback)
mockClient = MockWebServiceClient.createClient(applicationContext);
Source requestPayload = new StringSource("...");
Source responsePayload = new StringSource("...");
mockClient.sendRequest(RequestCreators.withPayload(requestPayload))
.andExpect(ResponseMatchers.payload(responsePayload));
~ Client side
1. Create a MockWebServiceServer instance by calling its factory methods
2. Set up request expectations by calling expect method (possibly use
RequestMatcher callback)
3. Create an appropriate response message by calling andRespond (possibly use
ResponseCreator callback)
4. Use the WebServiceTemplate
5. Call verify to check expectations
3.9.4 Interceptors
~ callbacks during message handling flow
~ EndpointInterceptor interface methods:
13/57
2. idempotent
3. not safe
3. Resource representations
resources are abstracted from its representations
resource can have various representations (text / html, image / png)
request uses header Accept to specify desired representation
response uses header Content-Type to indicate representation
4. Stateless conversation
no client content is being stored on server
client can maintain state (via HTTP links)
scalable architecture any server instance can serve the request
loose coupling no shared session
enables easy scaling of server in production environment
5. Hypermedia
resources contain hypermedia links
clients make state transitions only through actions that are dynamically identified
by these links
no need to update client when server is changed
client has to conform some server semantics
~ Idempotency (not just for RESTful applications)
multiple identical requests should have the same effect as a single request
helps with integration (client can retry request without side effects)
~ Advantages of REST
Scalability of component interactions
Protocol support
Languages
Scripts
Browsers only GET and POST through HTML
Redirect
Caching
Different representations
Simple Organizing resources
Pluggable formats (e.g. XML, JSON, Atom,...)
Simple load balancing
Decouples client from server
~ Security
possible with HTTP Basic or Digest
every request must have authentication (REST is stateless!!!)
transport level security requires SSL
message level security use of XML-DSIG and XML-Encryption
~ HTTP (and therefore also REST) is not suitable for long-running transactions (use
compensating transactions instead)
@Path("/customer/{id}")
@Component
@Scope("request")
public class CustomerService {
@GET
@Produces({"application/json"})
public Customer getCustomer(@PathParam("id") String customerId) {
return ...
}
}
@Controller
@RequestMapping("/pets/{petId}")
public class PetController {
@RequestMapping(method=RequestMethod.GET)
public @ResponseBody Pet getPet(@PathVariable String petId) {
return ...
}
}
primary mapping
value - primary mapping expressed by this annotation
~ URI template patterns
convenient access to selected parts of a URL in a @RequestMapping method
@RequestMapping(value="/pets/{petId}", method=RequestMethod.GET)
public @ResponseBody Pet getPet(@PathVariable String petId) {
return ... }
@RequestMapping("/spring-web/{symbolicName:[a-z-]+}-{version:\\d\\.\\d\\.\\d}
{extension:\\.[a-z]+}")
public void handle(@PathVariable String version, @PathVariable String
extension) {
// ...
}
}
@RequestMapping(value="/pets", method=RequestMethod.POST)
@ResponseStatus(HttpStatus. CREATED ) // 201
public void createPet(HttpServletRequest req, HttpServletResponse resp) {
... }
@RequestMapping(value="/pets/{petId}", method=RequestMethod.GET)
public @ResponseBody Pet getPet(@PathVariable String petId) {
return ... }
~ @RequestBody
Used with POST, PUT
HTTP request body is converted to method parameter
Content-Type of request specifies converter
@RequestMapping(value="/pets/{petId}", method=RequestMethod.PUT)
@ResponseStatus(HttpStatus.NO_CONTENT) // 204
public void updatePet(@RequestBody Pet updatePet ,
@PathVariable("petId") long id) {
// process updated order data and return empty response
...
}
17/57
GET
HEAD
OPTIONS
POST
18/57
5 Spring JMS
5.1 Where can Spring-JMS applications obtain their JMS resources
from
~ Spring JMS is designed to decouple application from JMS infrastructure
Spring instantiates JMS resources
Application uses Spring API (e.g. JmsTemplate)
~ Spring JMS also provides various deployment choices
Standalone JMS provider
ConnectionFactory implementation
<bean id="connectionFactory"
class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://localhost:8082"/>
</bean>
void
void
<T> T
<T> T
leverage of MessageConverter
~ Definition of MessageListenerContainer
21/57
<jms:listener-container connection-factory="connectionFactory">
<jms:listener destination="queue.orders" ref="orderService"
method="placeOrder"/>
<jms:listener destination="queue.confirmations" ref="confirmationListener"/>
</jms:listener-container>
Allows configuration of
task execution strategy
concurrency
container type
transaction manager
<jms:listener-container connection-factory="myConnectionFactory"
task-executor="myTaskExecutor"
destination-resolver="myDestinationResolver"
transaction-manager="myTransactionManager"
concurrency="10">
<jms:listener destination="queue.orders" ref="orderService"
method="placeOrder" />
<jms:listener destination="queue.confirmations" ref="confirmationLogger"
method="log" />
</jms:listener-container>
<jms:listener-container acknowledge="transacted">
...
</jms:listener-container>
22/57
6.2 If and if so, how is a local JMS transaction made available to the
JmsTemplate
~ JmsTemplate parameters for Session can be specified
sessionTransacted
sessionAcknowledgeMode will be ignored if sessionTransacted is
specified
~ Same Session instance is used for receiving and sending
Avoids duplicate messages messages are delivered once and only once.
Than for DB or synchronous JMS access can be used via @Transactional with
<tx:annotation-driven/> or <tx:advice/>
For asynchronous JMS reception can be used as parameter for JMS listener
container:
<jms:listener-container transaction-manager="transactionManager">
<jms:listener destination="queue.orders" ref="orderService"
method="placeOrder"/>
<jms:listener destination="queue.confirmations" ref="confirmationListener"/>
</jms:listener-container>
~ Third party frameworks like Hibernate must be configured specifically for JTA
~ JTA is requirement for EJB transaction handling (even with single transaction resource)
~ It is optional when Spring manages transactions (make sense only for more than one
transaction resources)
~ Switching from local to global transaction handling is very easy with Spring only little
configuration changes
<bean id="transactionManager"
class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager" ref="atomikosTransactionManager" />
<property name="userTransaction" ref="atomikosUserTransaction" />
</bean>
@Transactional(readOnly = true)
public List<Product> findAllProducts() {
return this.productDao.findAllProducts();
}
XML configuration via <tx:advice>
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<aop:config>
<aop:pointcut id="productServiceMethods"
expression="execution(* product.ProductService.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="productServiceMethods" />
</aop:config>
<tx:advice id="txAdvice" transaction-manager="myTxManager">
<tx:attributes>
<tx:method name="increasePrice*" propagation="REQUIRED" />
<tx:method name="someBusinessMethod" propagation="REQUIRES_NEW" />
<tx:method name="*" propagation="SUPPORTS" read-only="true" />
</tx:attributes>
</tx:advice>
<jms:listener-container acknowledge="transacted">
<jms:listener ref="jmsListener" destination="jms.queue"/>
</jms:listener-container>
Global transactions
use transaction-manager="transactionManager" instead of acknowledge
25/57
8 Spring Integration
8.1 Main concepts (Messages, Channels, Endpoint types)
Pay special attention to the various Endpoint types and how they're used!
~ Spring integration is implementation of Enterprise Integration Patterns
~ Principles
Components should be loosely coupled for modularity and testability
The framework should enforce separation of concerns between business logic and
integration logic
Extension points should be abstract in nature but within well-defined boundaries to
promote reuse and portability
~ Spring Integration uses declarative adapters to
Connect applications with external systems via various protocols
Lightweight messaging within Spring-based applications
Decouple application components from integration infrastructure
Converts external events into internal messages
Application components process only messages (typically only payload)
Can convert Internal message into external event
~ Main Components
Message
MessageChannel
MessageEndpoint
8.1.1 Message
public interface Message<T> {
MessageHeaders getHeaders();
T getPayload();
}
8.1.2 MessageEndpoint
invasive manner
MessageEndpoints are mapped to MessageChannels to isolate application
code from the infrastructure
Annotation support
@MessageEndpoint class level annotation indicates that class is used as
message endpoint
Method level annotation specifies type of the message endpoint
Method parameters can be annotated with @Header(headerParameter)
annotation Spring injects particular header value into that parameter
Inbound
Primary purpose of a Gateway is to hide Spring Integration messaging API - clients
code interacts with a simple interface only
It acts as proxy
Bi-directional
Typically Gateway will auto-create a temporary, anonymous reply channel, where it
will listen for the reply
Sometimes may prompt you to define a default-reply-channel (or replychannel with adapter gateways such as HTTP, JMS, etc.)
<int:gateway id="cafeService"
service-interface="org.cafeteria.Cafe"
default-request-channel="requestChannel"
default-reply-channel="replyChannel"/>
Apart from above inbound Messaging Gateway (which maps interface onto
messaging infrastructure) Spring provides Integration adapters gateways of two
types for various protocols (JMS, JPA, HTTP, TCP, RMI, Web Services, ...):
Inbound gateway receives external request, send if for internal processing and
sends reply via same protocol / interface
Outbound gateway sends request to external system and waits for response
These adapters are alternative API to Spring components like Spring MVC for
REST, Spring WS, Spring RMI,...
<int:service-activator input-channel="exampleChannel"
output-channel="replyChannel" ref="somePojo" method="someMethod"/>
header enricher
header filter
Creates new message, because Message is immutable
Annotation configuration
8.1.2.5 Filter
Annotation configuration
8.1.2.6 Router
Deciding what channel or channels should receive the Message next (if any)
Typically the decision is based upon the Message's content and/or metadata
available in the Message Headers
Implementations
PayloadTypeRouter
HeaderValueRouter
RecipientListRouter
XPath Router
Or user can specify custom router
@Router
public
@Router
public
@Router
public
@Router
public
29/57
8.1.2.7 Splitter
Splits received Message into multiple Messages and sends each of those to its
output channel
Often, they are upstream producers in a pipeline that includes an Aggregator
AbstractMessageSplitter sub-classes or any POJO (method accepts single
argument and return a value) can be configured as splitter
AbstractMessageSplitter fills appropriate message headers
CORRELATION_ID
SEQUENCE_SIZE
SEQUENCE_NUMBER
Annotation configuration
@Splitter
List<LineItem> extractItems(Order order) {
return order.getItems();
}
8.1.2.8 Aggregator
Annotation configuration
30/57
}
@ReleaseStrategy
public boolean releaseChecker(List<Message<?>> messages) {
...
}
@CorrelationStrategy
public String correlateBy(OrderItem item) {
...
}
}
<int:exception-type-router input-channel="inputChannel"
default-output-channel="defaultChannel">
<int:mapping exception-type="java.lang.IllegalArgumentException"
channel="illegalChannel" />
<int:mapping exception-type="java.lang.NullPointerException"
channel="npeChannel" />
</int:exception-type-router>
31/57
.build();
Message<String> message4 = MessageBuilder.withPayload("test4")
.setHeader("foo", 123)
.copyHeadersIfAbsent(message1.getHeaders())
.build();
Message<Integer> importantMessage = MessageBuilder.withPayload(99)
.setPriority(5)
.build();
Message<Integer> lessImportantMessage =
MessageBuilder.fromMessage(importantMessage)
.setHeaderIfAbsent(MessageHeaders.PRIORITY, 2)
.build();
~ MessagingTemplate
Provides sending / receiving support
Also conversion support
More invasive as usage of Messaging gateway
Sometimes MessagingTemplate is handier (e.g. in unit test)
sendTimeout and receiveTimeout properties may also be set on the template
MessagingTemplate template = new MessagingTemplate();
Message reply = template.sendAndReceive(someChannel, new GenericMessage("f"));
<int:chain input-channel="input">
<si-xml:marshalling-transformer
marshaller="marshaller" result-type="StringResult" />
<int:service-activator ref="someService" method="someMethod" />
<int:header-enricher>
<int:header name="foo" value="bar" />
</int:header-enricher>
<int:logging-channel-adapter level="INFO" log-full-message="true" />
32/57
</int:chain>
<int-stream:stdin-channel-adapter id="stdin"/>
<int-stream:stdout-channel-adapter id="stdout"/>
<int:bridge id="echo" input-channel="stdin" output-channel="stdout"/>
8.4 The different Channel types and how each of them should be used
Asynchronous
Consumer actively requests the message in separate thread/s
Consumer can't use transaction and security context of sender
Exceptions (typically) can't be propagated to the sender
To specify that channel is asynchronous, just specifying of XML sub-element
is needed
queue
task-executor
Channels
QueueChannel
Asynchronous PublishSubscribeChannel
ExecutorChannel
PriorityChannel
Simple Spring bean
no additional infrastructure needed (e.g. Broker)
can be optionally persisted (by JMS or JDBC)
Implemantations
DirectChannel
Point-to-Point semantics - single consumer
Synchronous handoff
Dispatches messages directly to subscriber
Dispatcher can have load-balancer strategy if multiple consumers are
subscribed (default strategy is round-robin)
Dispatcher have also failover property
Enables a single thread to perform the operations on "both sides" of the
channel this behavior is to support transactions
Message producer is blocked by consumers processing synchronous
<int:channel id="directChannel"/>
QueueChannel
34/57
Point-to-point semantics
Asynchronous handoff
Stores messages in internal queue until capacity is reached (default value is
Integer.MAX_VALUE)
Enforces first-in/first-out (FIFO) ordering
If capacity is reached, sender is blocked until some room is available or
timeout is reached
Can be configured with persistence store for messages
Receiver needs to poll from separate thread
Message flow will get stuck if there wouldn't be actively consuming
MessageEndpoint (with poller)
<int:channel id="queueChannel">
<queue capacity="25"/>
</int:channel>
PriorityChannel
QueueChannel sub-class
Processes classes based on priority attribute in message header
Comparator type custom logic can be specified via constructor
RendezvousChannel
QueueChannel sub-class
Direct handoff scenario sender is blocked until poller invoked receive()
It uses a SynchronousQueue (a zero-capacity implementation of
BlockingQueue)
Sender knows that some receiver has accepted the message
<int:channel id="rendezvousChannel"/>
<int:rendezvous-queue/>
</int:channel>
PublishSubscribeChannel
Broadcast message to all subscribers
Is intended for sending only
Consumers can't poll for messages
Have apply-sequence property for implementing Resequencer or
Aggregator EI patterns
Handoff types
synchronous publishes message in the sender's thread
<int:publish-subscribe-channel id="pubsubChannel"/>
ExecutorChannel
Point-to-point semantics
Asynchronous handoff
Supports same dispatcher configuration (load-balancer and failover
properties) as DirectChannel
Delegates to TaskExecutor to perform dispatch handler invocation
doesn't block senders thread
Does not support transaction spanning between sender and receiver
<int:channel id="executorChannelWithoutFailover">
35/57
8.4.1 ChannelInterceptor
Can be configured
Individually for each channel
WireTab
EI pattern
Interceptor that sends the Message to another channel without altering
existing flow
Useful for debugging and monitoring
<int:channel id="in">
<int:interceptors>
<int:wire-tap channel="logger" />
</int:interceptors>
</int:channel>
<int:logging-channel-adapter id="logger" level="DEBUG" />
nullChannel
logs any Message sent to it at DEBUG level and returning immediately
name nullChannel is reserved in application context
errorChannel
internally created PublishSubscribeChannel for sending error messages
may be overridden with a custom configuration
Are used by
Inbound gateways, that doesn't specify reply-channel explicitly
anonymous
point-to-point
36/57
8.6 The need for active polling and how to configure that
~ MessageEndpoint is by default passive component just waits to invoked
~ Consumer endpoints can be changed to active component by using of poller
Is needed for retrieval of messages from PollableChannel
Is used as sub-element in XML configuration of message endpoint
It is polling in one thread by default
37/57
<int:poller fixed-delay="1000">
<int:transactional transaction-manager="txManager" propagation="REQUIRED"
isolation="REPEATABLE_READ" timeout="10000" read-only="false" />
</int:poller>
9 Spring Batch
9.1 Main concepts (Job, Step, Job Instance, Job Execution, Step
Execution, etc.)
~ Spring Batch is a lightweight, comprehensive batch framework designed to enable the
development of robust batch applications vital for the daily operations of enterprise
systems
~ Provides reusable functions that are essential in processing
large volumes of records (usually not suitable for short transactions)
time based events (month-end calculations, notices or correspondence)
without user interaction (often handling restarts, error, retries, ...)
long-running jobs (usually in off peak hours/days)
~ Business Scenarios
Commit batch process periodically
Concurrent batch processing: parallel processing of a job
Staged, enterprise message-driven processing
Massively parallel batch processing
38/57
39/57
9.1.1 Job
jobRepository
list of Steps
Optional parameters
restartable
launching of a Job is considered to be a 'restart' if a JobExecution
already exists for the particular JobInstance
default value is true
Restart can start
Where job ended up last execution - need to persist
ExecutionContext intance (for Job and Step instances)
From the beginning if the state is not persisted
Entirely up to the developer to ensure that a new JobInstance is
created in this scenario
listeners
specifies list of Job's interceptors
<job id="job">
<flow id="job1.flow1" parent="flow1" next="step3" />
<step id="step3" parent="s3" />
</job>
<flow id="flow1">
<step id="step1" parent="s1" next="step2" />
<step id="step2" parent="s2" />
</flow>
Job Inheritance
concrete Jobs may inherit properties
"child" Job will combine its elements and attributes with the parent's
child will override any of the parent's properties by default
merge can be used to combine configurations
41/57
<listeners merge="true">
<listener ref="listenerTwo" />
</listeners>
</job>
9.1.2 JobInstance
9.1.3 JobLauncher
<bean id="jobLauncher"
class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
<property name="jobRepository" ref="jobRepository" />
</bean>
Running a Job
From command line
Java launcher class CommandLineJobRunner
Command line parameters
jobPath spring context XML configuration
jobName name/ID of the job to run
Optional job parameters key(type)=value pairs
bash$ java CommandLineJobRunner endOfDayJob.xml endOfDay
schedule.date(date)=2007/05/05
ExitCodeMapper converts ExitStatus returned as part of
JobExecution from JobLauncher into process exit code return value
42/57
(0=success,...)
From Spring driven application
Autowire or inject jobLauncher bean into client spring bean
Namespace parameters
Required
reader
writer
transaction-manager (defaults to transactionManager)
job-repository (defaults to jobRepository)
commit-interval
Optional
43/57
start-limit (on tasklet tag) how many times can be Step executed
allow-start-if-complete
Allow re-run previously completed step when job is restarting
Default is false
skip-limit (on chunk element) skip the chunk for particular exceptions
(specified by skippable-exception-classes (chunk sub-element))
In many scenarions processing shouldn't be terminated by error
It may be suitable to skip certain amount of errornous data
exceptions thrown from the ItemReader will not cause a rollback in this
scenario
<step id="step1">
<tasklet>
<chunk reader="flatFileItemReader" writer="itemWriter"
commit-interval="10" skip-limit= "10" >
<skippable-exception-classes >
<include class= "java.lang.Exception" />
<exclude class= "java.io.FileNotFoundException" />
</skippable-exception-classes >
</chunk>
</tasklet>
</step>
retry-limit
retry the chunk for particular exceptions
useful when error is transient and retry might succeed
supports also exclude
<step id="step1">
<tasklet>
<chunk reader="itemReader" writer="itemWriter" commit-interval="2"
retry-limit = "3" >
<retryable-exception-classes >
<include class= "org.springframework.
dao.DeadlockLoserDataAccessException" />
</retryable-exception-classes >
</chunk>
</tasklet>
</step>
44/57
@BeforeStep
@AfterStep
ChunkListener
@BeforeChunk
@AfterChunk
ItemReadListener
@BeforeRead
@AfterRead
@OnReadError
ItemProcessListener
45/57
@BeforeProcess
@AfterProcess
@OnProcessError
ItemWriteListener
@BeforeWrite
@AfterWrite
@OnWriteError
SkipListener
can intercept skipping single item on error
called right before commiting the transaction after chunk processing
<step id="step1">
<tasklet ref="myTasklet"/>
</step>
<job id="job">
46/57
</job>
Conditional flow
<job id="job">
<step id="stepA" parent="s1">
<next on="*" to="stepB" />
<next on="FAILED" to="stepC" />
</step>
<step id="stepB" parent="s2" next="stepC" />
<step id="stepC" parent="s3" />
</job>
'Fail' Element
instructs a Job to stop with a BatchStatus of FAILED
'Stop' Element
instructs a Job to stop with a BatchStatus of STOPPED
<job id="job">
<step id="step1" parent="s1" next="decision" />
<decision id="decision" decider="decider">
<next on="FAILED" to="step2" />
<next on="COMPLETED" to="step3" />
</decision>
<step id="step2" parent="s2" next="step3" />
<step id="step3" parent="s3" />
</job>
9.2.7 ItemReader
47/57
9.2.8 ItemProcessor
9.2.9 ItemWriter
9.2.10
executionContext.putLong(getKey(LINES_READ_COUNT), reader.getPosition());
ExecutionContext ecStep = stepExecution.getExecutionContext();
ExecutionContext ecJob = jobExecution.getExecutionContext();
9.2.11
Data are "promoted" to the Job's ExecutionContext after the step has finished
Listener must be configured with the keys related to the data in the
ExecutionContext that must be promoted
Optionally can be configured with a list of exit code patterns for which the promotion
should occur ("COMPLETED" is the default)
9.2.12
49/57
Step scope
Required in order to use late binding since the bean cannot actually be
instantiated until the Step starts, which allows the attributes to be found
9.2.13
50/57
9.4 What are job parameters and how are they used
9.5.2 FlatFileItemReader
LineMapper
Basic contract is that, given the current line and the line number with which it
is associated, the mapper should return a resulting domain object
public interface LineMapper<T> {
T mapLine(String line, int lineNumber) throws Exception;
}
9.5.3 LineTokenizer
Implementations
DelmitedLineTokenizer fields in a record are separated by a delimiter
FixedLengthTokenizer fields in a record are each a 'fixed width'
PatternMatchingCompositeLineTokenizer delimited against a pattern
9.5.4 FieldSetMapper
Takes a FieldSet object and maps its contents to an object (e.g. custom DTO, a
domain object, or a simple array)
Used in conjunction with the LineTokenizer to translate a line of data from a
resource into an object of the desired type
<bean id="fieldSetMapper"
class="org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper">
<property name="prototypeBeanName" value="player" />
</bean>
<bean id="player" class="org.springframework.batch.sample.domain.Player"
scope="prototype" />
52/57
9.5.5 DefaultLineMapper
File
USER;Smith;Peter;;T;20014539;F
LINEA;1044391041ABC037.49G201XX1383.12H
LINEB;2134776319DEF422.99M005LI
Parsing configuration
<bean id="orderFileLineMapper"
class="org.spr...PatternMatchingCompositeLineMapper">
<property name="tokenizers">
<map>
<entry key="USER*" value-ref="userTokenizer" />
<entry key="LINEA*" value-ref="lineATokenizer" />
<entry key="LINEB*" value-ref="lineBTokenizer" />
</map>
</property>
<property name="fieldSetMappers">
<map>
<entry key="USER*" value-ref="userFieldSetMapper" />
<entry key="LINE*" value-ref="lineFieldSetMapper" />
</map>
</property>
</bean>
53/57
HibernateCursorItemReader
StoredProcedureItemReader
~ Paging ItemReaders
Executing multiple queries where each query is bringing back a page of the results
Each query that is executed must specify the starting row number and the number
of rows that we want returned for the page
Implementations
JdbcPagingItemReader
Each database has its own strategy for providing paging support
We need to use a different PagingQueryProvider for each supported
database type
There is also the SqlPagingQueryProviderFactoryBean that will autodetect the database recommended best practise
Requires that you specify a select clause and a from clause.
You can also provide an optional where clause
These clauses will be used to build an SQL statement combined with the
required sortKey (required to be unique)
It will pass back one item per call to read in the same basic fashion as any
other ItemReader
The paging happens behind the scenes when additional rows are needed
<bean id="itemReader" class="org.spr...JdbcPagingItemReader">
<property name="dataSource" ref="dataSource" />
<property name="queryProvider">
<bean class="org.spr...SqlPagingQueryProviderFactoryBean">
54/57
JpaPagingItemReader
IbatisPagingItemReader
9.6.2 Repeat
~ Repetitive actions are common batch processing concern
~ Return value
Based on this value is decided if iteration should end
RepeatStatus.CONTINUABLE iteration should continue
RepeatStatus.FINISHED iteration should finish
~ Simplest implementation of RepeatOperations is RepeatTemplate
~ Spring Batch can iterate over the input
RepeatTemplate with RepeatCallback are used
Chunked step uses RepeatCallback implementation to call
ItemReader.read()
So user doesn't have to interact with RepeatTemplate directly
Iteration ends when ItemReader.read() returns null
9.6.3 Scaling and parallel processing
~ First check if simplest implementation meets your needs first
~ Use concurrent processing only if necessary
~ Two modes of parallel processing
Single process, multi-threaded
Multi-threaded Step
Parallel Steps
Partitioning a Step
Multi-process
Remote Chunking of Step
Partitioning a Step
~ Multi-threaded Step
Add a TaskExecutor to your Step configuration
55/57
<step id="loading">
<tasklet task-executor="taskExecutor" throttle-limit="20">...</tasklet>
</step>
~ Parallel Steps
<job id="job1">
<split id="split1" task-executor="taskExecutor" next="step4">
<flow>
<step id="step1" parent="s1" next="step2" />
<step id="step2" parent="s2" />
</flow>
<flow>
<step id="step3" parent="s3" />
</flow>
</split>
<step id="step4" parent="s4" />
</job>
56/57
Slaves can be
remote services (Multi-process scenario)
local threads of execution (Single process, multi-threaded scenario)
Each PatritionStep
has it's own ExecutionContext instance
will run only once
SPI (Service provider interface API intended to be implemented or extended by a
third party) in Spring Batch consists of
Special implementation of Step (PartitionStep)
Two strategy interfaces that need to be implemented for the specific
environment
PartitionHandler
StepExecutionSplitter
<step id="step1.master">
<partition step="step1" partitioner="partitioner">
<handler grid-size="10" task-executor="taskExecutor" />
</partition>
</step>
Spring Batch creates step executions for the partitions called "step1:partition0",
etc.
Partitioner generates execution contexts as input parameters for new
step executions only (no need to worry about restarts)
57/57