[id='spring_integration']
= Using {brandname} with Spring
{brandname} integrates with the Spring Framework to make it easy to add caching capabilities to your applications.

[[spring_cache_provider]]
== Setting Up {brandname} as a Spring Cache Provider
{brandname} implements the Spring SPI to offer high-performance, in-memory caching capabilities.

[[spring_add_support]]
=== Adding Spring Cache Support
The link:http://spring.io/[Spring Framework] offers a link:https://docs.spring.io/spring/docs/5.1.3.RELEASE/spring-framework-reference/integration.html#cache[cache abstraction] with two simple annotations:

* `@Cacheable` adds entries to the cache.
* `@CacheEvict` removes entries from the cache.

To add caching support to your application, do the following:

. Enable cache annotations in your application context either declaratively or programmatically.
+
* *Declaratively:* Add `<cache:annotation-driven/>` to your application context.
+
[source,xml,options="nowrap",subs=attributes+]
----
include::config_examples/spring_annotation_driven.xml[]
----
+
* *Programmatically:* Enable cache support as follows:
+
[source,java,options=nowrap]
----
include::code_examples/SpringEnableCaching.java[]
----
+
. Add {brandname} and the Spring integration module to your `pom.xml`.
+
* Embedded mode: `infinispan-spring5-embedded`
* Remote client-server mode: `infinispan-spring5-remote`
+
The following is an example with embedded mode:
+
[source,xml,options="nowrap",subs=attributes+]
----
include::dependencies_maven/spring_integration.xml[]
----

[[spring_configure_cache_provider]]
=== Configuring {brandname} as the Spring Cache Provider
The Spring cache provider SPI has two interfaces through which it interacts with {brandname}: `org.springframework.cache.CacheManager` and `org.springframework.cache.Cache`. The `CacheManager` interface acts as a factory for named `Cache` instances.

At runtime Spring looks for a `CacheManager` implementation that has a bean named `cacheManager` in the application context.

You can configure your application context either declaratively or programmatically.

* *Declaratively:*
+
[source,xml,options="nowrap",subs=attributes+]
----
include::config_examples/spring_cache_manager_bean.xml[]
----
* *Programmatically:*
+
[source,java,options=nowrap]
----
include::code_examples/SpringCacheManager.java[]
----

[[spring_add_caching]]
== Adding Caching to Your Application
Add the `@Cacheable` and `@CacheEvict` annotations to your application code.

[[spring_add_entries]]
=== Adding Cache Entries
The `@Cacheable` annotation adds returned values to a defined cache.

For instance, you have a data access object (DAO) for books. You want book instances to be cached after they have been loaded from the underlying database using `BookDao#findBook(Integer bookId)`.

Annotate the `findBook(Integer bookId)` method with `@Cacheable` as follows:

[source,java,options=nowrap]
----
include::code_examples/SpringCachableExample.java[]
----

Any `Book` instances returned from `findBook(Integer bookId)` are stored in a cache named `books`, using `bookId` as the key.

Note that "#bookId" is an expression in the link:http://static.springsource.org/spring/docs/current/spring-framework-reference/html/expressions.html[Spring Expression Language] that evaluates the `bookId` argument.

[IMPORTANT]
====
If your application needs to reference entries in the cache directly, you should include the `key` attribute. Without this attribute, Spring generates a hash from the supplied method arguments to use as the cache key.
====

[[spring_remove_entries]]
=== Deleting Cache Entries
The `@CacheEvict` annotation deletes entries from a defined cache.

Annotate the `deleteBook(Integer bookId)` method with `@CacheEvict` as follows:

[source,java,options=nowrap]
----
include::code_examples/SpringCacheEvictExample.java[]
----

[[spring_configure_timeouts]]
== Configuring Timeouts for Cache Operations

The {brandname} Spring cache provider defaults to blocking behaviour when performing read and write operations. By default operations are synchronous and do not time out. However, you might want to set a maximum time to wait for operations before timing out in some situations. For example, timeouts are useful if you need to ensure that an operation completes within a certain time and you can ignore the cached value.

`infinispan.spring.operation.read.timeout`::
Specifies the time, in milliseconds, to wait for read operations to complete. The default is `0` which means unlimited wait time.
`infinispan.spring.operation.write.timeout`::
Specifies the time, in milliseconds, to wait for write operations to complete. The default is `0` which means unlimited wait time.

To configure timeouts for cache operations, set the properties in the context XML for your application on either `SpringEmbeddedCacheManagerFactoryBean` or `SpringRemoteCacheManagerFactoryBean`.

[TIP]
====
In remote client-server mode, you can also add these properties to `hotrod-client.properties`.
====

The following example shows the timeout properties in the context XML for `SpringRemoteCacheManagerFactoryBean`:

[source,xml,options="nowrap",subs=attributes+]
----
include::config_examples/spring_remote_cache_manager_factory_bean.xml[]
----

[[spring_externalize_sessions]]
== Externalizing Sessions Using Spring Session

link:http://docs.spring.io/spring-session/docs/current/reference/html5[Spring Session] lets you externalize user session information into {brandname}.

To configure Spring Session integration in your application, do the following:

. Add dependencies to your `pom.xml`.
+
* Embedded mode: `infinispan-spring5-embedded`
* Remote client-server mode: `infinispan-spring5-remote`
+
The following is an example with remote client-server mode:
+
[source,xml,options="nowrap",subs=attributes+]
----
include::dependencies_maven/spring5_session_dependencies.xml[]
----
+
. Specify the appropriate FactoryBean to expose a `CacheManager` instance.
+
* Embedded mode: `SpringEmbeddedCacheManagerFactoryBean`
* Remote client-server mode: `SpringRemoteCacheManagerFactoryBean`
+
. Enable Spring Session with the appropriate annotation.
+
* Embedded mode: `@EnableInfinispanEmbeddedHttpSession`
* Remote client-server mode: `@EnableInfinispanRemoteHttpSession`
+
These annotations have optional parameters:
+
- `maxInactiveIntervalInSeconds` sets session expiration time in seconds. The default is `1800`.
- `cacheName` specifies the name of the cache that stores sessions. The default is `sessions`.

The following example shows a complete, annotation-based configuration:

[source,java,options=nowrap]
----
include::code_examples/SpringExternalizeSessions.java[]
----
