About¶
Fathom-JCache provides your application with seamless caching integration.
Installation¶
Add the Fathom-JCache artifact…
<dependency>
<groupId>com.gitblit.fathom</groupId>
<artifactId>fathom-jcache</artifactId>
<version>${fathom.version}</version>
</dependency>
… and also add your preferred JCache provider:
Provider | Artifact |
---|---|
Hazelcast | com.hazelcast:hazelcast |
Infinispan | org.infinispan:infinispan-jcache |
Ehcache | org.ehcache:jcache |
Layout¶
YourApp
└── src
└── main
└── java
└── conf
└── Caches.java
Note
This module depends on the value of the application.package
setting. If you have specified an application package then your Caches class must be ${package}/conf/Caches.java
.
Configuration¶
You don’t have to configure your JCache provider to use it. Each provider ships with default settings which allows you to get up-and-running very quickly.
If you need to specify a provider-specific configuration you may do so.
# Ehcache configuration file
# see http://ehcache.org/documentation
# specify 'jcache' to default to the Jcache default configuration
# ehcache.configurationFile = "classpath:conf/ehcache.xml"
ehcache.configurationFile = "jcache"
# Infinispan configuration file
# see http://infinispan.org/docs/7.0.x/user_guide/user_guide.html
# specify 'jcache' to default to the Jcache default configuration
# infinispan.configurationFile = "classpath:conf/infinispan.xml"
infinispan.configurationFile = "jcache"
# Hazelcast configuration file
# see http://hazelcast.org/documentation
# specify 'jcache' to default to the Jcache default configuration
# hazelcast.configurationFile = "classpath:conf/hazelcast.xml"
hazelcast.configurationFile = "jcache"
Multiple Providers on the classpath¶
In the event that you have multiple providers on the classpath at the same time, Fathom will pick the first one loaded by the JVM unless you specify a preference.
# Set the preferred JCache provider.
# If unspecified, the first provider discovered will be used.
# You may specify a full provider classname or you may specify
# a nickname for an already registered JCache implementation
# such as: ehcache, infinispan, hazelcast
jcache.preferredProvider = ""
One scenario where you might have multiple providers is using one for DEV
mode and a different one for PROD
mode. This would be the caching analog of using an SQL db like SQLite or H2 for development and PostgreSQL for production.
Usage¶
Defining your Caches¶
Create a conf/Caches.java
class.
package conf;
public class Caches extends CachesModule {
public static final String EMPLOYEE_CACHE = "employeeCache";
@Override
protected void setup(Settings settings, CacheManager cacheManager) {
// example employee cache
cacheManager.createCache(EMPLOYEE_CACHE, new MutableConfiguration()
.setExpiryPolicyFactory(ModifiedExpiryPolicy.factoryOf(Duration.ONE_MINUTE))
.setStatisticsEnabled(true)
.setStoreByValue(true));
}
}
Using your Caches¶
The most elegant way to use Fathom’s JCache integration is with annotations.
In the following non-functional example we are annotating our employee DAO singleton to specify that all methods in this DAO access the EMPLOYEE_CACHE defined in our conf/Caches.java
class.
We are also annotating the get
, getAll
, delete
, and save
methods. Calling these methods will transparently manage the cache.
@Singleton
@CacheDefaults(cacheName = Caches.EMPLOYEE_CACHE)
public class EmployeeDao {
private static final Logger log = LoggerFactory.getLogger(EmployeeDao.class);
public EmployeeDao() {
}
@CacheResult
public Employee get(int id) {
log.info("Getting employee #{} by id", id);
Employee employee = employees.get(id);
return employee;
}
@CacheResult
public List<Employee> getAll() {
log.info("Getting all employees");
return new ArrayList<>(employees.values());
}
@CacheRemoveAll
public Employee delete(int id) {
Employee employee = employees.get(id);
employees.remove(id);
return employee;
}
@CacheRemoveAll
public Employee save(Employee employee) {
return put(employee);
}
}
Warning
It’s important to note that the JCache method interceptors, like all Guice method interceptors, are bound by the same limitations - including method scope.
- Classes must be public or package-private.
- Classes must be non-final
- Methods must be public, package-private or protected
- Methods must be non-final
- Instances must be created by Guice by an @Inject-annotated or no-argument constructor It is not possible to use method interception on instances that aren’t constructed by Guice.
Viewing and Managing your Caches¶
Fathom does not provide a mechansim to view & manage your caches, however, several JCache providers register MBeans which allow cache viewing and management via JConsole or VisualVM.