Questo contenuto non è disponibile nella lingua selezionata.

Chapter 29. The Infinispan CDI Module


29.1. The Infinispan CDI Module

Infinispan includes Context and Dependency Injection (CDI) in the infinispan-cdi module. The infinispan-cdi module offers:

  • Configuration and injection using the Cache API.
  • A bridge between the cache listeners and the CDI event system.
  • Partial support for the JCACHE caching annotations.

29.2. Using Infinispan CDI

29.2.1. Infinispan CDI Prerequisites

The following is a list of prerequisites to use the Infinispan CDI module with Red Hat JBoss Data Grid:

  • Ensure that the most recent version of the infinispan-cdi module is used.
  • Ensure that the correct dependency information is set.

29.2.2. Set the CDI Maven Dependency

The CDI module is included in the Infinispan jar for each deployment type, and no additional dependencies are required.

Library Mode

In Library mode the infinispan-embedded artifact contains the CDI module, and should be added as a dependency as seen in the below example:

<dependency>
    <groupId>org.infinispan</groupId>
    <artifactId>infinispan-embedded</artifactId>
    <version>${infinispan.version}</version>
</dependency>
Copy to Clipboard Toggle word wrap

Remote Client-Server Mode

In Remote Client-Server mode the infinispan-remote artifact contains the CDI module, and should be added as a dependency as seen in the below example:

<dependency>
    <groupId>org.infinispan</groupId>
    <artifactId>infinispan-remote</artifactId>
    <version>${infinispan.version}</version>
</dependency>
Copy to Clipboard Toggle word wrap

29.3. Using the Infinispan CDI Module

29.3.1. Using the Infinispan CDI Module

The Infinispan CDI module can be used for the following purposes:

  • To configure and inject Infinispan caches into CDI Beans and Java EE components.
  • To configure cache managers.
  • To control storage and retrieval using CDI annotations.

29.3.2. Configure and Inject Infinispan Caches

29.3.2.1. Inject an Infinispan Cache

An Infinispan cache is one of the multiple components that can be injected into the project’s CDI beans.

The following code snippet illustrates how to inject a cache instance into the CDI bean:

public class MyCDIBean {
    @Inject
    Cache<String, String> cache;
}
Copy to Clipboard Toggle word wrap

29.3.2.2. Inject a Remote Infinispan Cache

The code snippet to inject a normal cache is slightly modified to inject a remote Infinispan cache, as follows:

public class MyCDIBean {
    @Inject
    RemoteCache<String, String> remoteCache;
}
Copy to Clipboard Toggle word wrap

29.3.2.3. Set the Injection’s Target Cache

29.3.2.3.1. Set the Injection’s Target Cache

The following are the three steps to set an injection’s target cache:

  1. Create a qualifier annotation.
  2. Add a producer class.
  3. Inject the desired class.
29.3.2.3.2. Create a Qualifier Annotation

To use CDI to return a specific cache, create custom cache qualifier annotations as follows:

Custom Cache Qualifier

@javax.inject.Qualifier
@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SmallCache {}
Copy to Clipboard Toggle word wrap

Use the created @SmallCache qualifier to specify how to create specific caches.

29.3.2.3.3. Add a Producer Class

The following code snippet illustrates how the @SmallCache qualifier (created in the previous step) specifies a way to create a cache:

Using the @SmallCache Qualifier

import org.infinispan.configuration.cache.Configuration;
import org.infinispan.configuration.cache.ConfigurationBuilder;
import org.infinispan.cdi.ConfigureCache;
import javax.enterprise.inject.Produces;

public class CacheCreator {
    @ConfigureCache("smallcache")
    @SmallCache
    @Produces
    public Configuration specialCacheCfg() {
        return new ConfigurationBuilder()
                   .eviction()
                       .strategy(EvictionStrategy.LRU)
                       .maxEntries(10)
                   .build();
    }
}
Copy to Clipboard Toggle word wrap

The elements in the code snippet are:

  • @ConfigureCache specifies the name of the cache.
  • @SmallCache is the cache qualifier.
29.3.2.3.4. Inject the Desired Class

Use the @SmallCache qualifier and the new producer class to inject a specific cache into the CDI bean as follows:

public class MyCDIBean {
    @Inject @SmallCache
    Cache<String, String> mySmallCache;
}
Copy to Clipboard Toggle word wrap

29.3.3. Configure Cache Managers with CDI

29.3.3.1. Configure Cache Managers with CDI

A Red Hat JBoss Data Grid Cache Manager (both embedded and remote) can be configured using CDI. Whether configuring an embedded or remote cache manager, the first step is to specify a default configuration that is annotated to act as a producer.

29.3.3.2. Specify the Default Configuration

Specify a method annotated as a producer for the Red Hat JBoss Data Grid configuration object to replace the default Infinispan Configuration. The following sample configuration illustrates this step:

Specifying the Default Configuration

public class Config {
    @Produces
    public Configuration defaultEmbeddedConfiguration () {
        return new ConfigurationBuilder()
                         .eviction()
                                 .strategy(EvictionStrategy.LRU)
                                 .maxEntries(100)
                         .build();
    }
}
Copy to Clipboard Toggle word wrap

Note

CDI adds a @Default qualifier if no other qualifiers are provided.

If a @Produces annotation is placed in a method that returns a Configuration instance, the method is invoked when a Configuration object is required.

In the provided example configuration, the method creates a new Configuration object which is subsequently configured and returned.

29.3.3.3. Override the Creation of the Embedded Cache Manager

Creating Non Clustered Caches

After a producer method is annotated, this method will be called when creating an EmbeddedCacheManager, as follows:

public class Config {

    @Produces
    @ApplicationScoped
    public EmbeddedCacheManager defaultEmbeddedCacheManager() {
        Configuration cfg = new ConfigurationBuilder()
                                    .eviction()
                                            .strategy(EvictionStrategy.LRU)
                                            .maxEntries(150)
                                    .build();
        return new DefaultCacheManager(cfg);
    }
}
Copy to Clipboard Toggle word wrap

The @ApplicationScoped annotation specifies that the method is only called once.

Creating Clustered Caches

The following configuration can be used to create an EmbeddedCacheManager that can create clustered caches.

public class Config {

	@Produces
	@ApplicationScoped
	public EmbeddedCacheManager defaultClusteredCacheManager() {
		GlobalConfiguration g = new GlobalConfigurationBuilder()
				.clusteredDefault()
				.transport()
				.clusterName("InfinispanCluster")
				.build();
		Configuration cfg = new ConfigurationBuilder()
				.eviction()
				.strategy(EvictionStrategy.LRU)
				.maxEntries(150)
				.build();
		return new DefaultCacheManager(g, cfg);
	}
}
Copy to Clipboard Toggle word wrap

Invoke the Method to Generate an EmbeddedCacheManager

The method annotated with @Produces in the non clustered method generates Configuration objects. The methods in the clustered cache example annonated with @Produces generate EmbeddedCacheManager objects.

Add an injection as follows in your CDI Bean to invoke the appropriate annotated method. This generates EmbeddedCacheManager and injects it into the code at runtime.

Generate an EmbeddedCacheManager

...
@Inject
EmbeddedCacheManager cacheManager;
...
Copy to Clipboard Toggle word wrap

29.3.3.4. Configure a Remote Cache Manager

The RemoteCacheManager is configured in a manner similar to EmbeddedCacheManagers, as follows:

Configuring the Remote Cache Manager

public class Config {
	@Produces
	@ApplicationScoped
	public RemoteCacheManager defaultRemoteCacheManager() {
           Configuration conf = new ConfigurationBuilder().addServer().host(ADDRESS).port(PORT).build();
            return new RemoteCacheManager(conf);
	}
}}
Copy to Clipboard Toggle word wrap

29.3.3.5. Configure Multiple Cache Managers with a Single Class

A single class can be used to configure multiple cache managers and remote cache managers based on the created qualifiers. An example of this is as follows:

Configure Multiple Cache Managers

public class Config {
    @Produces
    @ApplicationScoped
    public org.infinispan.manager.EmbeddedCacheManager
    defaultEmbeddedCacheManager() {
        Configuration cfg = new ConfigurationBuilder()
                .eviction()
                .strategy(EvictionStrategy.LRU)
                .maxEntries(150)
                .build();
        return new DefaultCacheManager(cfg);
    }

    @Produces
    @ApplicationScoped
    @DefaultClustered
    public org.infinispan.manager.EmbeddedCacheManager
    defaultClusteredCacheManager() {
        GlobalConfiguration g = new GlobalConfigurationBuilder()
                .clusteredDefault()
                .transport()
                .clusterName("InfinispanCluster")
                .build();
        Configuration cfg = new ConfigurationBuilder()
                .eviction()
                .strategy(EvictionStrategy.LRU)
                .maxEntries(150)
                .build();
        return new DefaultCacheManager(g, cfg);
    }

    @Produces
    @ApplicationScoped
    @DefaultRemote
    public RemoteCacheManager
    defaultRemoteCacheManager() {
        org.infinispan.client.hotrod.configuration.Configuration conf = new org.infinispan.client.hotrod.configuration.ConfigurationBuilder().addServer().host(ADDRESS).port(PORT).build();
        return new RemoteCacheManager(conf);
    }

    @Produces
    @ApplicationScoped
    @RemoteCacheInDifferentDataCentre
    public RemoteCacheManager newRemoteCacheManager() {
        org.infinispan.client.hotrod.configuration.Configuration confid = new org.infinispan.client.hotrod.configuration.ConfigurationBuilder().addServer().host(ADDRESS_FAR_AWAY).port(PORT).build();
        return new RemoteCacheManager(confid);
    }
}
Copy to Clipboard Toggle word wrap

29.4. Storage and Retrieval Using CDI Annotations

29.4.1. Configure Cache Annotations

Specific CDI annotations are accepted for the JCache (JSR-107) specification. All included annotations are located in the javax.cache package.

The annotations intercept method calls on CDI beans and perform storage and retrieval tasks as a result of these interceptions.

Important

CDI is supported in both Remote Client-Server Mode and Library Mode; however, annotations such as @CachePut, @CacheRemove, @CacheRemoveAll, and @CacheResult cannot be used in Remote Client-Server Mode.

29.4.2. Enable Cache Annotations

JBoss Data Grid includes two sets of interceptors depending on how they are used. Interceptors can be added to the CDI bean archive using the beans.xml file.

Option 1: CDI Interceptors

Adding the following code adds interceptors such as the InjectedCacheResultInterceptor, InjectedCachePutInterceptor, InjectedCacheRemoveEntryInterceptor and the InjectedCacheRemoveAllInterceptor:

Adding CDI Interceptors

<beans xmlns="http://java.sun.som/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.jcache.annotation.InjectedCacheResultInterceptor</class>
		<class>org.infinispan.jcache.annotation.InjectedCachePutInterceptor</class>
		<class>org.infinispan.jcache.annotation.InjectedCacheRemoveEntryInterceptor</class>
		<class>org.infinispan.jcache.annotation.InjectedCacheRemoveAllInterceptor</class>
	</interceptors>
</beans>
Copy to Clipboard Toggle word wrap

Option 2: JCache Interceptors

Adding the following code adds interceptors such as the CacheResultInterceptor, CachePutInterceptor, CacheRemoveEntryInterceptor and the CacheRemoveAllInterceptor:

Adding JCache Interceptors

<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.jcache.annotation.CacheResultInterceptor</class>
      <class>org.infinispan.jcache.annotation.CachePutInterceptor</class>
      <class>org.infinispan.jcache.annotation.CacheRemoveEntryInterceptor</class>
      <class>org.infinispan.jcache.annotation.CacheRemoveAllInterceptor</class>
   </interceptors>

</beans>
Copy to Clipboard Toggle word wrap

Note

The listed interceptors must appear in the beans.xml file for Red Hat JBoss Data Grid to use javax.cache annotations.

29.4.3. Caching the Result of a Method Invocation

29.4.3.1. Caching the Result of a Method Invocation

A common practice for time or resource intensive operations is to save the results in a cache for future access. The following code is an example of such an operation:

public String toCelsiusFormatted(float fahrenheit) {
	return
		NumberFormat.getInstance()
		.format((fahrenheit * 5 / 9) - 32)
		+ " degrees Celsius";
}
Copy to Clipboard Toggle word wrap

A common approach is to cache the results of this method call and to check the cache when the result is next required. The following is an example of a code snippet that looks up the result of such an operation in a cache. If the results are not found, the code snippet runs the toCelsiusFormatted method again and stores the result in the cache.

float f = getTemperatureInFahrenheit();
Cache<Float, String>
	fahrenheitToCelsiusCache = getCache();
String celsius =
	fahrenheitToCelsiusCache = get(f);
     if (celsius == null) {
	     celsius = toCelsiusFormatted(f);
	     fahrenheitToCelsiusCache.put(f, celsius);
     }
Copy to Clipboard Toggle word wrap

In such cases, the Infinispan CDI module can be used to eliminate all the extra code in the related examples. Annotate the method with the @CacheResult annotation instead, as follows:

@javax.cache.annotation.CacheResult
public String toCelsiusFormatted(float fahrenheit) {
	return NumberFormat.getInstance()
	.format((fahrenheit * 5 / 9) - 32)
	+ " degrees Celsius";
}
Copy to Clipboard Toggle word wrap

Due to the annotation, Infinispan checks the cache and if the results are not found, it invokes the toCelsiusFormatted() method call.

Note

The Infinispan CDI module allows checking the cache for saved results, but this approach should be carefully considered before application. If the results of the call should always be fresh data, or if the cache reading requires a remote network lookup or deserialization from a cache loader, checking the cache before call method invocation can be counter productive.

29.4.3.2. Specify the Cache Used

Add the following optional attribute (cacheName) to the @CacheResult annotation to specify the cache to check for results of the method call:

@CacheResult(cacheName = "mySpecialCache")
public String doSomething(String parameter) {
<!-- Additional configuration information here -->
}
Copy to Clipboard Toggle word wrap

29.4.3.3. Cache Keys for Cached Results

As a default, the @CacheResult annotation creates a key for the results fetched from a cache. The key consists of a combination of all parameters in the relevant method.

Create a custom key using the @CacheKey annotation as follows:

Create a Custom Key

@CacheResult
public String doSomething
	(@CacheKey String p1,
	@CacheKey String p2,
	String dontCare) {
<!-- Additional configuration information here -->
}
Copy to Clipboard Toggle word wrap

In the specified example, only the values of p1 and p2 are used to create the cache key. The value of dontCare is not used when determining the cache key.

29.4.3.4. Generate a Custom Key

Generate a custom key as follows:

import javax.cache.annotation.CacheKey;
import javax.cache.annotation.CacheKeyGenerator;
import javax.cache.annotation.CacheKeyInvocationContext;
import java.lang.annotation.Annotation;

public class MyCacheKeyGenerator implements CacheKeyGenerator {

   @Override
   public CacheKey generateCacheKey(CacheKeyInvocationContext<? extends Annotation> ctx) {

      return new MyCacheKey(
            ctx.getAllParameters()[0].getValue()
      );
   }
}
Copy to Clipboard Toggle word wrap

The listed method constructs a custom key. This key is passed as part of the value generated by the first parameter of the invocation context.

To specify the custom key generation scheme, add the optional parameter cacheKeyGenerator to the @CacheResult annotation as follows:

@CacheResult(cacheKeyGenerator = MyCacheKeyGenerator.class)
public void doSomething(String p1, String p2) {
<!-- Additional configuration information here -->
}
Copy to Clipboard Toggle word wrap

Using the provided method, p1 contains the custom key.

29.4.4. Cache Operations

29.4.4.1. Update a Cache Entry

When the method that contains the @CachePut annotation is invoked, a parameter (normally passed to the method annotated with @CacheValue) is stored in the cache.

Sample @CachePut Annotated Method

import javax.cache.annotation.CachePut;
import javax.cache.annotation.CacheKey;
import javax.cache.annotation.CacheValue;

@CachePut (cacheName = "personCache")
public void updatePerson
	(@CacheKey long personId,
	@CacheValue Person newPerson) {
<!-- Additional configuration information here -->
	}
Copy to Clipboard Toggle word wrap

Further customization is possible using cacheName and cacheKeyGenerator in the @CachePut method. Additionally, some parameters in the invoked method may be annotated with @CacheKey to control key generation.

See Also: Cache keys for Cached Results

29.4.4.2. Remove an Entry from the Cache

The following is an example of a @CacheRemoveEntry annotated method that is used to remove an entry from the cache:

Removing an Entry from the Cache

import javax.cache.annotation.CacheRemoveEntry;
import javax.cache.annotation.CacheKey;

@CacheRemoveEntry (cacheName = "cacheOfPeople")
public void changePersonName
	(@CacheKey long personId,
	string newName) {
<!-- Additional configuration information here -->
	}
Copy to Clipboard Toggle word wrap

The annotation accepts the optional cacheName and cacheKeyGenerator attributes.

29.4.4.3. Clear the Cache

Invoke the @CacheRemoveAll method to clear all entries from the cache.

Clear All Entries from the Cache with @CacheRemoveAll

import javax.cache.annotation.CacheRemoveAll;

@CacheRemoveAll (cacheName = "statisticsCache")
public void resetStatistics() {
<!-- Additional configuration information here -->
}
Copy to Clipboard Toggle word wrap

As displayed in the example, this annotation accepts an optional cacheName attribute.

Torna in cima
Red Hat logoGithubredditYoutubeTwitter

Formazione

Prova, acquista e vendi

Community

Informazioni sulla documentazione di Red Hat

Aiutiamo gli utenti Red Hat a innovarsi e raggiungere i propri obiettivi con i nostri prodotti e servizi grazie a contenuti di cui possono fidarsi. Esplora i nostri ultimi aggiornamenti.

Rendiamo l’open source più inclusivo

Red Hat si impegna a sostituire il linguaggio problematico nel codice, nella documentazione e nelle proprietà web. Per maggiori dettagli, visita il Blog di Red Hat.

Informazioni su Red Hat

Forniamo soluzioni consolidate che rendono più semplice per le aziende lavorare su piattaforme e ambienti diversi, dal datacenter centrale all'edge della rete.

Theme

© 2025 Red Hat