此内容没有您所选择的语言版本。
Chapter 17. JCache (JSR-107) API
Data Grid provides an implementation of JCache 1.0 API ( JSR-107 ). JCache specifies a standard Java API for caching temporary Java objects in memory. Caching java objects can help get around bottlenecks arising from using data that is expensive to retrieve (i.e. DB or web service), or data that is hard to calculate. Caching these type of objects in memory can help speed up application performance by retrieving the data directly from memory instead of doing an expensive roundtrip or recalculation. This document specifies how to use JCache with the Data Grid implementation of the specification, and explains key aspects of the API.
17.1. Creating embedded caches 复制链接链接已复制到粘贴板!
Prerequisites
-
Ensure that
cache-api
is on your classpath. Add the following dependency to your
pom.xml
:<dependency> <groupId>org.infinispan</groupId> <artifactId>infinispan-jcache</artifactId> </dependency>
<dependency> <groupId>org.infinispan</groupId> <artifactId>infinispan-jcache</artifactId> </dependency>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Procedure
- Create embedded caches that use the default JCache API configuration as follows:
17.1.1. Configuring embedded caches 复制链接链接已复制到粘贴板!
-
Pass the URI for custom Data Grid configuration to the
CachingProvider.getCacheManager(URI)
call as follows:
By default, the JCache API specifies that data should be stored as storeByValue
, so that object state mutations outside of operations to the cache, won’t have an impact in the objects stored in the cache. Data Grid has so far implemented this using serialization/marshalling to make copies to store in the cache, and that way adhere to the spec. Hence, if using default JCache configuration with Data Grid, data stored must be marshallable.
Alternatively, JCache can be configured to store data by reference (just like Data Grid or JDK Collections work). To do that, simply call:
Cache<String, String> cache = cacheManager.createCache("namedCache", new MutableConfiguration<String, String>().setStoreByValue(false));
Cache<String, String> cache = cacheManager.createCache("namedCache",
new MutableConfiguration<String, String>().setStoreByValue(false));
17.2. Creating remote caches 复制链接链接已复制到粘贴板!
Prerequisites
-
Ensure that
cache-api
is on your classpath. Add the following dependency to your
pom.xml
:<dependency> <groupId>org.infinispan</groupId> <artifactId>infinispan-jcache-remote</artifactId> </dependency>
<dependency> <groupId>org.infinispan</groupId> <artifactId>infinispan-jcache-remote</artifactId> </dependency>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Procedure
- Create caches on remote Data Grid servers and use the default JCache API configuration as follows:
17.2.1. Configuring remote caches 复制链接链接已复制到粘贴板!
Hot Rod configuration files include infinispan.client.hotrod.cache.*
properties that you can use to customize remote caches.
-
Pass the URI for your
hotrod-client.properties
file to theCachingProvider.getCacheManager(URI)
call as follows:
17.3. Store and retrieve data 复制链接链接已复制到粘贴板!
Even though JCache API does not extend neither java.util.Map not java.util.concurrent.ConcurrentMap, it providers a key/value API to store and retrieve data:
Contrary to standard java.util.Map, javax.cache.Cache comes with two basic put methods called put and getAndPut. The former returns void
whereas the latter returns the previous value associated with the key. So, the equivalent of java.util.Map.put(K) in JCache is javax.cache.Cache.getAndPut(K).
Even though JCache API only covers standalone caching, it can be plugged with a persistence store, and has been designed with clustering or distribution in mind. The reason why javax.cache.Cache offers two put methods is because standard java.util.Map put call forces implementors to calculate the previous value. When a persistent store is in use, or the cache is distributed, returning the previous value could be an expensive operation, and often users call standard java.util.Map.put(K) without using the return value. Hence, JCache users need to think about whether the return value is relevant to them, in which case they need to call javax.cache.Cache.getAndPut(K) , otherwise they can call java.util.Map.put(K, V) which avoids returning the potentially expensive operation of returning the previous value.
Here’s a brief comparison of the data manipulation APIs provided by java.util.concurrent.ConcurrentMap and javax.cache.Cache APIs.
Operation | java.util.concurrent.ConcurrentMap<K, V> | javax.cache.Cache<K, V> |
---|---|---|
store and no return | N/A |
|
store and return previous value |
|
|
store if not present |
|
|
retrieve |
|
|
delete if present |
|
|
delete and return previous value |
|
|
delete conditional |
|
|
replace if present |
|
|
replace and return previous value |
|
|
replace conditional |
|
|
Comparing the two APIs, it’s obvious to see that, where possible, JCache avoids returning the previous value to avoid operations doing expensive network or IO operations. This is an overriding principle in the design of JCache API. In fact, there’s a set of operations that are present in java.util.concurrent.ConcurrentMap , but are not present in the javax.cache.Cache because they could be expensive to compute in a distributed cache. The only exception is iterating over the contents of the cache:
Operation | java.util.concurrent.ConcurrentMap<K, V> | javax.cache.Cache<K, V> |
---|---|---|
calculate size of cache |
| N/A |
return all keys in the cache |
| N/A |
return all values in the cache |
| N/A |
return all entries in the cache |
| N/A |
iterate over the cache |
use |
|
17.5. Clustering JCache instances 复制链接链接已复制到粘贴板!
Data Grid JCache implementation goes beyond the specification in order to provide the possibility to cluster caches using the standard API. Given a Data Grid configuration file configured to replicate caches like this:
infinispan.xml
You can create a cluster of caches using this code: