diff --git a/spring-batch-docs/src/main/asciidoc/appendix.adoc b/spring-batch-docs/src/main/asciidoc/appendix.adoc
index 4b3f51ef2..79cf854bd 100644
--- a/spring-batch-docs/src/main/asciidoc/appendix.adoc
+++ b/spring-batch-docs/src/main/asciidoc/appendix.adoc
@@ -13,10 +13,14 @@ include::attributes.adoc[]
.Available Item Readers
[options="header"]
|===============
-|Item Reader|Description
+|Item Reader|Description|Thread-safe
+|`AbstractItemStreamItemReader`|Abstract base class that combines the `ItemStream` and `ItemReader` interfaces.|Yes
|`AbstractItemCountingItemStreamItemReader`|Abstract base class that provides basic
restart capabilities by counting the number of items returned from
- an `ItemReader`.
+ an `ItemReader`.|No
+|`AbstractPagingItemReader`|Abstract base class that provides basic paging features|No
+|`AbstractPaginatedDataItemReader`|Abstract base class that provides basic paging features based on Spring Data's
+ paginated facilities|No
|`AggregateItemReader`|An `ItemReader` that delivers a list as its
item, storing up objects from the injected `ItemReader` until they
are ready to be packed out as a collection. This class must be used
@@ -25,46 +29,49 @@ include::attributes.adoc[]
records by returning an `AggregateItem` which responds `true` to its
query methods (`isHeader()` and `isFooter()`). Note that this reader
is not part of the library of readers provided by Spring Batch
- but given as a sample in `spring-batch-samples`.
+ but given as a sample in `spring-batch-samples`.|Yes
|`AmqpItemReader`|Given a Spring `AmqpTemplate`, it provides
synchronous receive methods. The `receiveAndConvert()` method
- lets you receive POJO objects.
+ lets you receive POJO objects.|Yes
|`KafkaItemReader`|An `ItemReader` that reads messages from an Apache Kafka topic.
It can be configured to read messages from multiple partitions of the same topic.
-This reader stores message offsets in the execution context to support restart capabilities.
+This reader stores message offsets in the execution context to support restart capabilities.|No
|`FlatFileItemReader`|Reads from a flat file. Includes `ItemStream`
- and `Skippable` functionality. See link:readersAndWriters.html#flatFileItemReader["`FlatFileItemReader`"].
+ and `Skippable` functionality. See link:readersAndWriters.html#flatFileItemReader["`FlatFileItemReader`"].|No
|`HibernateCursorItemReader`|Reads from a cursor based on an HQL query. See
- link:readersAndWriters.html#cursorBasedItemReaders[`Cursor-based ItemReaders`].
-|`HibernatePagingItemReader`|Reads from a paginated HQL query.
+ link:readersAndWriters.html#cursorBasedItemReaders[`Cursor-based ItemReaders`].|No
+|`HibernatePagingItemReader`|Reads from a paginated HQL query.|Yes
|`ItemReaderAdapter`|Adapts any class to the
- `ItemReader` interface.
+ `ItemReader` interface.|Yes
|`JdbcCursorItemReader`|Reads from a database cursor over JDBC. See
- link:readersAndWriters.html#cursorBasedItemReaders["`Cursor-based ItemReaders`"].
+ link:readersAndWriters.html#cursorBasedItemReaders["`Cursor-based ItemReaders`"].|No
|`JdbcPagingItemReader`|Given an SQL statement, pages through the rows,
such that large datasets can be read without running out of
- memory.
+ memory.|Yes
|`JmsItemReader`|Given a Spring `JmsOperations` object and a JMS
destination or destination name to which to send errors, provides items
received through the injected `JmsOperations#receive()`
- method.
-|`JpaPagingItemReader`|Given a JPQL statement, pages through the
+ method.|Yes
+|`JpaCursorItemReader`|Executes a JPQL query and iterates over the returned result set|No
+|`JpaPagingItemReader`|Given a JPQL query, pages through the
rows, such that large datasets can be read without running out of
- memory.
-|`ListItemReader`|Provides the items from a list, one at a
- time.
+ memory.|Yes
+|`ListItemReader`|Provides the items from a list, one at a time.|No
|`MongoItemReader`|Given a `MongoOperations` object and a JSON-based MongoDB
- query, provides items received from the `MongoOperations#find()` method.
+ query, provides items received from the `MongoOperations#find()` method.|Yes
|`Neo4jItemReader`|Given a `Neo4jOperations` object and the components of a
Cyhper query, items are returned as the result of the Neo4jOperations.query
- method.
+ method.|Yes
|`RepositoryItemReader`|Given a Spring Data `PagingAndSortingRepository` object,
a `Sort`, and the name of method to execute, returns items provided by the
- Spring Data repository implementation.
+ Spring Data repository implementation.|Yes
|`StoredProcedureItemReader`|Reads from a database cursor resulting from the
- execution of a database stored procedure. See link:readersAndWriters.html#StoredProcedureItemReader[`StoredProcedureItemReader`]
-|`StaxEventItemReader`|Reads over StAX. see link:readersAndWriters.html#StaxEventItemReader[`StaxEventItemReader`].
-|`JsonItemReader`|Reads items from a Json document. see link:readersAndWriters.html#JsonItemReader[`JsonItemReader`].
+ execution of a database stored procedure. See link:readersAndWriters.html#StoredProcedureItemReader[`StoredProcedureItemReader`]|No
+|`StaxEventItemReader`|Reads over StAX. see link:readersAndWriters.html#StaxEventItemReader[`StaxEventItemReader`].|No
+|`JsonItemReader`|Reads items from a Json document. see link:readersAndWriters.html#JsonItemReader[`JsonItemReader`].|No
+|`AvroItemReader`|Reads items from a resource containing serialized Avro objects.|No
+|`LdifReader`|Reads items from a LDIF resource and returns them as `LdapAttributes`|No
+|`MappingLdifReader`|Reads items from a LDIF resource and uses a `RecordMapper` to map them to domain objects|No
|===============
@@ -75,55 +82,55 @@ This reader stores message offsets in the execution context to support restart c
.Available Item Writers
[options="header"]
|===============
-|Item Writer|Description
-|`AbstractItemStreamItemWriter`|Abstract base class that combines the
- `ItemStream` and
- `ItemWriter` interfaces.
+|Item Writer|Description|Thread-safe
+|`AbstractItemStreamItemWriter`|Abstract base class that combines the`ItemStream` and`ItemWriter` interfaces.|Yes
|`AmqpItemWriter`|Given a Spring `AmqpTemplate`, provides
for a synchronous `send` method. The `convertAndSend(Object)`
- method lets you send POJO objects.
+ method lets you send POJO objects.|Yes
|`CompositeItemWriter`|Passes an item to the `write` method of each item
- in an injected `List` of `ItemWriter` objects.
+ in an injected `List` of `ItemWriter` objects.|Yes
|`FlatFileItemWriter`|Writes to a flat file. Includes `ItemStream` and
- Skippable functionality. See link:readersAndWriters.html#flatFileItemWriter["`FlatFileItemWriter`"].
+ Skippable functionality. See link:readersAndWriters.html#flatFileItemWriter["`FlatFileItemWriter`"].|No
|`HibernateItemWriter`|This item writer is Hibernate-session aware
and handles some transaction-related work that a non-"`hibernate-aware`"
item writer would not need to know about and then delegates
- to another item writer to do the actual writing.
+ to another item writer to do the actual writing.|Yes
|`ItemWriterAdapter`|Adapts any class to the
- `ItemWriter` interface.
+ `ItemWriter` interface.|Yes
|`JdbcBatchItemWriter`|Uses batching features from a
`PreparedStatement`, if available, and can
take rudimentary steps to locate a failure during a
- `flush`.
+ `flush`.|Yes
|`JmsItemWriter`|Using a `JmsOperations` object, items are written
- to the default queue through the `JmsOperations#convertAndSend()` method.
+ to the default queue through the `JmsOperations#convertAndSend()` method.|Yes
|`JpaItemWriter`|This item writer is JPA `EntityManager`-aware
and handles some transaction-related work that a non-"`JPA-aware`"
`ItemWriter` would not need to know about and
- then delegates to another writer to do the actual writing.
+ then delegates to another writer to do the actual writing.|Yes
|`KafkaItemWriter`|Using a `KafkaTemplate` object, items are written to the default topic through the
`KafkaTemplate#sendDefault(Object, Object)` method by using a `Converter` to map the key from the item.
- A delete flag can also be configured to send delete events to the topic.
+ A delete flag can also be configured to send delete events to the topic.|No
|`MimeMessageItemWriter`|Using Spring's `JavaMailSender`, items of type `MimeMessage`
- are sent as mail messages.
+ are sent as mail messages.|Yes
|`MongoItemWriter`|Given a `MongoOperations` object, items are written
through the `MongoOperations.save(Object)` method. The actual write is delayed
- until the last possible moment before the transaction commits.
+ until the last possible moment before the transaction commits.|Yes
|`Neo4jItemWriter`|Given a `Neo4jOperations` object, items are persisted through the
`save(Object)` method or deleted through the `delete(Object)`, as dictated by the
- `ItemWriter's` configuration
+ `ItemWriter's` configuration|Yes
|`PropertyExtractingDelegatingItemWriter`|Extends `AbstractMethodInvokingDelegator`
creating arguments on the fly. Arguments are created by retrieving
the values from the fields in the item to be processed (through a
`SpringBeanWrapper`), based on an injected array of field
- names.
+ names.|Yes
|`RepositoryItemWriter`|Given a Spring Data `CrudRepository` implementation,
- items are saved through the method specified in the configuration.
+ items are saved through the method specified in the configuration.|Yes
|`StaxEventItemWriter`|Uses a `Marshaller` implementation to
convert each item to XML and then writes it to an XML file by using
- StAX.
+ StAX.|No
|`JsonFileItemWriter`|Uses a `JsonObjectMarshaller` implementation to
- convert each item to Json and then writes it to a Json file.
+ convert each item to Json and then writes it to a Json file.|No
+|`AvroItemWriter`|Serializes data to an `WritableResource` using Avro|No
+|`ListItemWriter`|Item writer that writes items to a `List`.|No
|===============
diff --git a/spring-batch-docs/src/main/asciidoc/readersAndWriters.adoc b/spring-batch-docs/src/main/asciidoc/readersAndWriters.adoc
index c6cedf18f..8692ebbad 100644
--- a/spring-batch-docs/src/main/asciidoc/readersAndWriters.adoc
+++ b/spring-batch-docs/src/main/asciidoc/readersAndWriters.adoc
@@ -2787,6 +2787,25 @@ When using an `ItemReader` that is not thread safe, Spring Batch offers the
thread safe. Spring Batch provides a `SynchronizedItemStreamReaderBuilder` to construct
an instance of the `SynchronizedItemStreamReader`.
+For example, the `FlatFileItemReader` is *not* thread-safe and cannot be used in
+a multi-threaded step. This reader can be decorated with a `SynchronizedItemStreamReader`
+in order to use it safely in a multi-threaded step. Here is an example of how to decorate
+such a reader:
+
+[source, java]
+----
+@Bean
+public SynchronizedItemStreamReader
+ * This adapter is thread-safe as long as the delegate
+ * This adapter is thread-safe as long as the delegate
+ * This writer is thread-safe as long as the delegate ItemReader is
+ * thread-safe.
+ * ItemWriter is
+ * thread-safe.
+ * ItemWriter is
+ * thread-safe.
+ *
+ * This reader is thread-safe as long as the delegate AmqpTemplate
+ * implementation is thread-safe.
+ *
+ * This writer is thread-safe as long as the delegate AmqpTemplate
+ * implementation is thread-safe.
+ *
+ * This reader is not thread-safe. + *
+ * * @author David Turanski * @author Mahmoud Ben Hassine * @author Song JaeGeun diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/avro/AvroItemWriter.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/avro/AvroItemWriter.java index 411cdc7f8..39effa80c 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/avro/AvroItemWriter.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/avro/AvroItemWriter.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 the original author or authors. + * Copyright 2019-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -44,6 +44,10 @@ import org.springframework.util.Assert; * * This does not support restart on failure. * + *+ * This writer is not thread-safe. + *
+ * * @since 4.2 * @author David Turanski * @author Mahmoud Ben Hassine diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/AbstractPaginatedDataItemReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/AbstractPaginatedDataItemReader.java index 2965b27c6..a5bbe826d 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/AbstractPaginatedDataItemReader.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/AbstractPaginatedDataItemReader.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,8 +28,11 @@ import java.util.Iterator; * Spring Data's paginated facilities. It also handles the semantics required for * restartability based on those facilities. * + * This reader is not thread-safe. + * * @author Michael Minella * @author Glenn Renfro + * @author Mahmoud Ben Hassine * @since 2.2 * @param+ * Subclasses are inherently not thread-safe. + *
+ * * @author Lucas Ward * @author Peter Zozom * @author Robert Kasanicky diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/AbstractPagingItemReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/AbstractPagingItemReader.java index e2cb8f6e9..92a23f125 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/AbstractPagingItemReader.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/AbstractPagingItemReader.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2022 the original author or authors. + * Copyright 2006-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,8 +36,11 @@ import org.springframework.util.ClassUtils; * position. * * + * This reader is not thread-safe. + * * @author Thomas Risberg * @author Dave Syer + * @author Mahmoud Ben Hassine * @since 2.0 */ public abstract class AbstractPagingItemReader+ * This reader is not thread-safe. + *
+ * * @author Lucas Ward * @author Peter Zozom * @author Robert Kasanicky diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/StoredProcedureItemReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/StoredProcedureItemReader.java index d6f74827a..d95e75b7f 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/StoredProcedureItemReader.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/StoredProcedureItemReader.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2022 the original author or authors. + * Copyright 2006-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -55,6 +55,10 @@ import org.springframework.util.ClassUtils; * This class is modeled after the similarJdbcCursorItemReader class.
*
*
+ * + * This reader is not thread-safe. + *
+ * * @author Thomas Risberg * @author Mahmoud Ben Hassine */ diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/FlatFileItemReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/FlatFileItemReader.java index a2b3253bc..c990d9770 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/FlatFileItemReader.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/FlatFileItemReader.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2022 the original author or authors. + * Copyright 2006-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,6 +43,10 @@ import org.springframework.util.StringUtils; * rethrown as {@link FlatFileParseException} adding information about the problematic * line and its line number. * + *+ * This reader is not thread-safe. + *
+ * * @author Robert Kasanicky * @author Mahmoud Ben Hassine */ diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ldif/LdifReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ldif/LdifReader.java index 3464143c5..7c16ceceb 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ldif/LdifReader.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ldif/LdifReader.java @@ -1,5 +1,5 @@ /* - * Copyright 2005-2022 the original author or authors. + * Copyright 2005-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -55,7 +55,12 @@ import org.springframework.util.ClassUtils; * or not to require the resource to exist before processing. In the case of a value set * to false, a warning is logged instead of an exception being thrown. * + *+ * This reader is not thread-safe. + *
+ * * @author Keith Barlow + * @author Mahmoud Ben Hassine * */ public class LdifReader extends AbstractItemCountingItemStreamItemReader+ * This reader is not thread-safe. + *
+ * * @author Keith Barlow + * @author Mahmoud Ben Hassine * */ public class MappingLdifReader- * Stateless, so automatically restartable. + * This writer is stateless, therefore it is thread-safe and automatically restartable. *
* * @author Dave Syer diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/support/AbstractItemStreamItemReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/support/AbstractItemStreamItemReader.java index 2a77922d9..b0db566bc 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/support/AbstractItemStreamItemReader.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/support/AbstractItemStreamItemReader.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2007 the original author or authors. + * Copyright 2006-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,7 +23,10 @@ import org.springframework.batch.item.ItemStreamSupport; /** * Base class for {@link ItemReader} implementations. * + * This abstract reader is thread-safe. + * * @author Dave Syer + * @author Mahmoud Ben Hassine * */ public abstract class AbstractItemStreamItemReader+ * This reader is not thread-safe. + *
+ * * @author Dave Syer * @author jojoldu * diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/support/ListItemWriter.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/support/ListItemWriter.java index 7f3ff2626..786fa4656 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/support/ListItemWriter.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/support/ListItemWriter.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2022 the original author or authors. + * Copyright 2014-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,12 @@ import java.util.ArrayList; import java.util.List; /** + * Item writer that writes items to aList.
+ *
+ * + * This writer is not thread-safe. + *
+ * * @author mminella * @author Mahmoud Ben Hassine */