Introduktion til JCache

1. Oversigt

Kort sagt, JCache er standard-caching-API til Java. I denne vejledning skal vi se, hvad JCache er, og hvordan vi kan bruge det.

2. Maven-afhængigheder

For at bruge JCache skal vi tilføje følgende afhængighed til vores pom.xml:

 javax.cache cache-api 1.0.0-PFD 

Bemærk, at vi kan finde den nyeste version af biblioteket i Maven Central Repository.

Vi skal også tilføje en implementering af API'en til vores pom.xml; vi bruger Hazelcast her:

 com.hazelcast hazelcast 3.9-EA 

Vi kan også finde den nyeste version af Hazelcast i dets Maven Central Repository.

3. JCache-implementeringer

JCache implementeres af forskellige cacheløsninger:

  • JCache Reference Implementation
  • Hazelcast
  • Oracle sammenhæng
  • Terracotta Ehcache
  • Infinispan

Bemærk, at i modsætning til andre referenceimplementeringer, Det anbefales ikke at bruge JCache Reference Implementation i produktionen, da det forårsager nogle samtidige problemer.

4. Hovedkomponenter

4.1. Cache

Det Cache interface har følgende nyttige metoder:

  • få() - tager nøglen til et element som en parameter og returnerer elementets værdi; det vender tilbage nul hvis nøglen ikke findes i Cache
  • getAll () - flere nøgler kan sendes til denne metode som en Sæt; tmetoden returnerer de givne nøgler og tilknyttede værdier som en Kort
  • getAndRemove () - metoden henter en værdi ved hjælp af dens nøgle og fjerner elementet fra Cache
  • sætte() - indsætter et nyt element i Cache
  • klar() - fjerner alle elementer i Cache
  • indeholderKey () - kontrollerer, om en Cache indeholder en bestemt nøgle

Som vi kan se, er metodernes navne stort set selvforklarende. For mere information om disse metoder og andre, besøg Javadoc.

4.2. CacheManager

CacheManager er en af ​​API'ens vigtigste grænseflader. Det giver os mulighed for at etablere, konfigurere og lukke Cacher.

4.3. CachingProvider

CachingProvider er en grænseflade, der giver os mulighed for at oprette og styre livscyklussen for CacheManagers.

4.4. Konfiguration

Konfiguration er en grænseflade, der gør det muligt for os at konfigurere Cacher. Det har en konkret implementering - MutableConfiguration og en underflade - Komplet konfiguration.

5. Oprettelse af en Cache

Lad os se, hvordan vi kan skabe en simpel Cache:

CachingProvider cachingProvider = Caching.getCachingProvider (); CacheManager cacheManager = cachingProvider.getCacheManager (); MutableConfiguration config = ny MutableConfiguration (); Cache cache = cacheManager .createCache ("simpleCache", config); cache.put ("nøgle1", "værdi1"); cache.put ("key2", "value2"); cacheManager.close ();

Alt hvad vi laver er:

  • Oprettelse af en CachingProvider objekt, som vi bruger til at konstruere en CacheManager objekt
  • Oprettelse af en MutableConfiguration objekt, som er en implementering af Konfiguration interface
  • Oprettelse af en Cache objekt ved hjælp af CacheManager objekt, vi oprettede tidligere
  • Ved at lægge alle poster skal vi cache i vores Cache objekt
  • Lukning af CacheManager for at frigøre de ressourcer, der bruges af Cache

Hvis vi ikke leverer nogen implementering af JCache i vores pom.xml, vil følgende undtagelse blive kastet:

javax.cache.CacheException: Ingen CachingProviders er konfigureret

Årsagen til dette er, at JVM ikke kunne finde nogen konkret implementering af getCacheManager () metode.

6. EntryProcessor

EntryProcessor giver os mulighed for at ændre Cache poster, der bruger atomoperationer uden at skulle tilføje dem til Cache. For at bruge det skal vi implementere EntryProcessor grænseflade:

offentlig klasse SimpleEntryProcessor implementerer EntryProcessor, Serializable {public String process (MutableEntry entry, Object ... args) throw EntryProcessorException {if (entry.exists ()) {String current = entry.getValue (); entry.setValue (nuværende + "- ændret"); returstrøm; } returnere null; }}

Lad os nu bruge vores EntryProcessor implementering:

@Test offentligt ugyldigt nårModifyValue_thenCorrect () {this.cache.invoke ("nøgle", ny SimpleEntryProcessor ()); assertEquals ("værdi - modificeret", cache.get ("nøgle")); }

7. Event lyttere

Eventlyttere tillader os at tage handlinger ved udløsning af en af ​​de begivenhedstyper, der er defineret i EventType enum, som er:

  • OPRETTET
  • OPDATERET
  • FJERNET
  • UDLØBT

Først skal vi implementere grænseflader til de begivenheder, vi skal bruge.

For eksempel, hvis vi vil bruge OPRETTET og OPDATERET hændelsestyper, så skal vi implementere grænsefladerne CacheEntryCreatedListener og CacheEntryUpdatedListener.

Lad os se et eksempel:

offentlig klasse SimpleCacheEntryListener implementerer CacheEntryCreatedListener, CacheEntryUpdatedListener, Serialiserbar {privat boolsk opdateret; privat boolsk oprettet; // standard getters public void onUpdated (Iterable hændelser) kaster CacheEntryListenerException {this.updated = true; } offentlig ugyldighed onCreated (Iterable events) kaster CacheEntryListenerException {this.created = true; }}

Lad os nu køre vores test:

@Test offentligt ugyldigt nårRunEvent_thenCorrect () kaster InterruptedException {this.listenerConfiguration = new MutableCacheEntryListenerConfiguration (FactoryBuilder.factoryOf (this.listener), null, false, true); this.cache.registerCacheEntryListener (this.listenerConfiguration); assertEquals (falsk, this.listener.getCreated ()); this.cache.put ("nøgle", "værdi"); assertEquals (sandt, this.listener.getCreated ()); assertEquals (falsk, this.listener.getUpdated ()); this.cache.put ("nøgle", "newValue"); assertEquals (sandt, this.listener.getUpdated ()); }

8. CacheLoader

CacheLoader tilladeros til at bruge gennemlæsningstilstandat behandle cache som hoveddatalager og læse data fra det.

I et virkeligt scenarie kan vi få cachen til at læse data fra faktisk lager.

Lad os se på et eksempel. Først skal vi implementere CacheLoader grænseflade:

offentlig klasse SimpleCacheLoader implementerer CacheLoader {public String load (Integer key) kaster CacheLoaderException {return "fromCache" + key; } offentlig Map loadAll (Iterable keys) kaster CacheLoaderException {Map data = new HashMap (); for (int-nøgle: nøgler) {data.put (nøgle, indlæs (nøgle)); } returnere data }}

Og nu, lad os bruge vores CacheLoader implementering:

offentlig klasse CacheLoaderTest {privat cache-cache; @Før offentlig tomrumsopsætning () {CachingProvider cachingProvider = Caching.getCachingProvider (); CacheManager cacheManager = cachingProvider.getCacheManager (); MutableConfiguration config = ny MutableConfiguration () .setReadThrough (true) .setCacheLoaderFactory (ny FactoryBuilder.SingletonFactory (ny SimpleCacheLoader ())); this.cache = cacheManager.createCache ("SimpleCache", konfiguration); } @Test offentlig ugyldig nårReadingFromStorage_thenCorrect () {for (int i = 1; i <4; i ++) {Strengværdi = cache.get (i); assertEquals ("fromCache" + i, værdi); }}}

9. Konklusion

I denne vejledning har vi set hvad JCache er og udforsket nogle af dens vigtige funktioner i et par praktiske scenarier.

Som altid kan den fulde implementering af denne vejledning findes på GitHub.