<dependency> <groupId>org.infinispan</groupId> <artifactId>infinispan-cdi</artifactId> <version>${infinispan.version}</version> </dependency>
Infinispan includes integration with CDI in the infinispan-cdi module. Configuration and injection of the Inifispan's Cache API is provided, and it is planned to bridge Cache listeners to the CDI event system. The module also provide partial support of the JCACHE (JSR-107) caching annotations - for further details see Chapter 8 of the JCACHE specification.
All you need is org.infinispan:infinispan-cdi:
<dependency> <groupId>org.infinispan</groupId> <artifactId>infinispan-cdi</artifactId> <version>${infinispan.version}</version> </dependency>
We recommend using the latest final version of the infinispan-cdi module. This module is available since Infinispan version 5.0.0.CR8.
By default you can inject the default Infinispan cache. Let's look at the following example:
import javax.inject.Inject; public class GreetingService { @Inject private Cache<String, String> cache; public String greet(String user) { String cachedValue = cache.get(user); if (cachedValue == null) { cachedValue = "Hello " + user; cache.put(user, cachedValue); } return cachedValue; } }
If you want to use a specific cache you just have to provide your own cache configuration and cache qualifier. For example, if you want to use a custom cache for the GreetingService you should write your own qualifier (for example GreetingCache) and define it's configuration:
... import javax.inject.Qualifier; @Qualifier @Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface GreetingCache { }
... import org.infinispan.cdi.Infinispan; import javax.enterprise.inject.Produces; public class Config { @Infinispan("greeting-cache") // this is the cache name. @GreetingCache // this is the cache qualifier. @Produces public Configuration greetingCacheConfiguration() { return new Configuration().fluent() .eviction().strategy(EvictionStrategy.FIFO).maxEntries(4) .build(); } // the same example but without providing a custom configuration (the default cache configuration will be used). @Infinispan("greeting-cache") @GreetingCache @Produces public Configuration greetingCacheConfiguration; }
To use this cache in the GreetingService you just have to add the qualifier @GeetingCache on your cache injection. Simple!
You can override the default cache configuration used by the default cache manager. To do this you just have to create one Configuration producer annotated with the @OverrideDefault qualifier as illustrated in the following snippet:
... import org.infinispan.cdi.OverrideDefault; public class Config { @OverrideDefault @Produces public Configuration defaultConfiguration() { return new Configuration().fluent() .eviction().strategy(EvictionStrategy.FIFO).maxEntries(4) .build(); } }
It's also possible to override the default cache manager used.
public class Config { @OverrideDefault @Produces public EmbeddedCacheManager defaultCacheManager() { return new DefaultCacheManager(new Configuration().fluent() .eviction().strategy(EvictionStrategy.FIFO).maxEntries(4) .build()); } }
It's possible to use a custom cache manager for one or more caches. To do this you just have to annotate the cache manager producer with the cache(s) qualifier you want to associate with it. Look at the following example:
... import javax.enterprise.context.ApplicationScoped; public class Config { @GreetingCache @Produces @ApplicationScoped public EmbeddedCacheManager specificCacheManager() { return new DefaultCacheManager(new Configuration().fluent() .expiration().lifespan(60000l) .build()); } }
With the above code the GreetingCache will be associated with the produced cache manager. In this case each cache entry in the GreetingCache will have a lifespan of 60 seconds.
To work properly the EmbeddedCacheManager producer must have the scope application. Otherwise each GreetingCache injected will be associated to a new instance of DefaultCacheManager.
The infinispan-cdi module provides a partial support of JCACHE caching annotations. These annotations provide a simple way to handle common use cases. The following caching annotations are defined in this specification:
@CacheResult which caches the result of a method call
@CacheRemoveEntry which removes an entry from the cache
@CacheRemoveAll which removes all entries from a cache
These annotations must only be used on methods.
In order to use the above annotations the following interceptors must be declared in the beans.xml of your application.
<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd"> <interceptors> <class>org.infinispan.cdi.interceptor.CacheResultInterceptor</class> <class>org.infinispan.cdi.interceptor.CacheRemoveEntryInterceptor</class> <class>org.infinispan.cdi.interceptor.CacheRemoveAllInterceptor</class> </interceptors> </beans>
The following snippet of code shows how the use of the @CacheResult annotation simplifies the caching of the Greetingservice#greet method results. The only thing to do is to annotate this method with @CacheResult.
import javax.cache.interceptor.CacheResult; public class GreetingService { @CacheResult public String greet(String user) { return "Hello" + user; } }
The first version of the GreetingService and the above version have exactly the same behavior. The only difference is the cache used. By default the cache used is the fully qualified name of the annotated method with it's parameter types (in this example org.infinispan.example.GreetingService.greet(java.lang.String)).
To use another cache you just have to specify the cacheName attribute of the annotation. For example:
@CacheResult(cacheName = "greeting-cache")