Spring Cache -abstraktion perusteet
Lisätkää välimuistitus koskematta liiketoimintalogiikkaan käyttämällä @Cacheable-, @CachePut- ja @CacheEvict-annotaatioita.
Spring Cache -abstraktion perusteet on ilmainen Spring Boot 4:n kattava opas-oppitunti CoddyKitissä. Tämä on oppitunti 1/4. Voit lukea tästä oppimispolusta kokonaan mitkä tahansa 3 oppituntia ilmaiseksi — sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä käytännön harjoittelun sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Oppitunti kuuluu Spring Boot 4:n kattava opas-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Spring Boot 4:n kattava opas-kurssilla on yhteensä 4 oppituntia.
Miksi välimuistabstraktio?
Välimuisti tallentaa raskaan toiminnon tuloksen, jotta seuraava samanlainen kutsu voidaan palauttaa välittömästi. Naiivissa toteutuksessa if (map.containsKey(key)) ...-logiikka hajautuu palvelumenetelmiin ja sekoittaa välimuistin käsittelyn liiketoimintalogiikkaan.
Springin Cache Abstraction ratkaisee tämän ongelman. Välimuisti määritetään annotaatioilla, ja Spring lisää logiikan AOP-proxyjen avulla. Menetelmän runko voi keskittyä varsinaiseen työhön.
- @Cacheable — palauttaa välimuistissa olevan arvon tai suorittaa menetelmän ja tallentaa tuloksen
- @CachePut — suorittaa menetelmän aina ja päivittää sitten välimuistin
- @CacheEvict — poistaa merkintöjä välimuistista
Välimuistien käyttöönotto
Abstraktio on otettava käyttöön erikseen. Lisätkää @EnableCaching konfiguraatioluokkaan tai pääsovellusluokkaan. Tämä käskee Springiä etsimään välimuistiannotaatioita ja luomaan proxyt, jotka sieppaavat menetelmäkutsut.
Jos CacheManager-beania ei ole määritetty, Spring Boot konfiguroi automaattisesti yksinkertaisen muistinsisäisen ConcurrentMapCacheManager-toteutuksen. Se sopii kehitykseen, mutta tuotannossa se vaihdetaan yleensä Caffeineen tai Redisiin.
@SpringBootApplication
@EnableCaching
public class StoreApplication {
public static void main(String[] args) {
SpringApplication.run(StoreApplication.class, args);
}
}@Cacheable käytännössä
@Cacheable on välimuistin keskeinen annotaatio. Kun menetelmää kutsutaan ensimmäisen kerran tietyllä argumentilla, Spring suorittaa menetelmän ja tallentaa tuloksen avaimen alle. Myöhemmillä kutsuilla samalla argumentilla menetelmän runko ohitetaan kokonaan ja välimuistissa oleva arvo palautetaan.
value- tai cacheNames-attribuutti nimeää loogisen välimuistin. Oletusarvoisesti avain muodostetaan menetelmän argumenteista.
@Service
public class BookService {
@Cacheable("books")
public Book findByIsbn(String isbn) {
// Simulates a slow database lookup
simulateSlowService();
return new Book(isbn, "Spring in Action");
}
}Välimuistiavaimen muodostaminen
Oletusarvoisesti avain johdetaan menetelmän parametreista. Yhden parametrin tapauksessa kyseinen parametri toimii avaimena. Usean parametrin tapauksessa Spring käyttää ne yhdistävää SimpleKey-avainta.
Voitte hallita avainta key-attribuutin SpEL-lausekkeella. Tämä on tärkeää, kun vain osan argumentista halutaan muodostavan avaimen.
key = "#isbn"— käyttää isbn-argumenttiakey = "#book.id"— käyttää argumentin ominaisuuttakey = "#root.methodName + #id"— yhdistää metatiedot ja argumentit
@Cacheable(cacheNames = "books", key = "#book.isbn")
public Book refresh(Book book) {
return reload(book);
}Ehdollinen välimuistitus
Joskus välimuistiin halutaan tallentaa vain tietyt tulokset. Kaksi SpEL-attribuuttia auttaa tässä:
- condition — arvioidaan ennen menetelmän suorittamista; välimuistitus tehdään vain, jos ehto on tosi
- unless — arvioidaan menetelmän suorittamisen jälkeen (tulos on saatavilla
#result-muuttujan kautta); kun ehto on tosi, välimuistitus estetään
Yleinen toimintamalli on olla tallentamatta null-tuloksia, jotta epäonnistunutta hakua ei muisteta.
@Cacheable(
cacheNames = "books",
key = "#isbn",
condition = "#isbn.length() > 0",
unless = "#result == null")
public Book findByIsbn(String isbn) {
return repository.lookup(isbn);
}@CachePut: suorita aina ja päivitä aina
Toisin kuin @Cacheable, @CachePut suorittaa menetelmän aina ja tallentaa sen palauttaman arvon välimuistiin. Käyttäkää sitä luonti- ja päivitysoperaatioissa, joissa tuoreen tuloksen halutaan päivittävän välimuistin.
Määrittäkää avaimeksi sama arvo, jota @Cacheable käyttää, jotta myöhempi findByIsbn-kutsu näkee päivitetyn merkinnän vanhentuneen sijaan.
@CachePut(cacheNames = "books", key = "#result.isbn")
public Book updateBook(Book book) {
return repository.save(book);
}Cacheable vai CachePut — keskeinen valinta
@Cacheable-annotaation lisääminen päivitysmenetelmään voi tuntua houkuttelevalta, mutta se on virhe: @Cacheable saattaa ohittaa menetelmän kokonaan, jos avain on jo olemassa, jolloin tallennusta ei suoriteta.
- Lukumetodit, joiden tulee päättyä osumaan välimuistissa → @Cacheable
- Kirjoitusmetodit, jotka on aina suoritettava mutta joiden tulee päivittää välimuisti → @CachePut
Älkää käyttäkö molempia samassa menetelmässä — niiden semantiikat ovat ristiriidassa: toinen voi ohittaa suorituksen, kun taas toinen suoritetaan aina.
@CacheEvict: merkintöjen poistaminen
@CacheEvict poistaa tietoja välimuistista yleensä poiston yhteydessä tai kun merkintä vanhentuu. Voitte kohdistaa poiston yhteen avaimeen tai tyhjentää koko välimuistin määrittämällä allEntries = true.
Oletusarvoisesti poisto tehdään sen jälkeen, kun menetelmä on palautunut onnistuneesti. Määrittäkää beforeInvocation = true, jos haluatte poistaa merkinnän myös silloin, kun menetelmä heittää poikkeuksen.
@CacheEvict(cacheNames = "books", key = "#isbn")
public void deleteBook(String isbn) {
repository.delete(isbn);
}
@CacheEvict(cacheNames = "books", allEntries = true)
public void reloadCatalog() {
repository.reloadAll();
}Useiden operaatioiden yhdistäminen @Caching-annotaatiolla
Kun yksi menetelmä tarvitsee useita välimuistioperaatioita — esimerkiksi yhden välimuistin päivittämisen ja toisen tyhjentämisen — ryhmitelkää ne @Caching-annotaatiolla. Se hyväksyy cacheable-, put- ja evict-annotaatioiden taulukot.
Näin vältetään rajoitus, jonka vuoksi samaa annotaatiotyyppiä ei voi vanhemmissa Java-versioissa toistaa suoraan menetelmässä, ja toisiinsa liittyvät operaatiot pysyvät yhdessä.
@Caching(
put = { @CachePut(cacheNames = "booksById", key = "#book.id") },
evict = { @CacheEvict(cacheNames = "bookSearch", allEntries = true) })
public Book save(Book book) {
return repository.save(book);
}Sisäisen kutsun sudenkuoppa
Springin välimuistitus toimii beanin ympärille käärityn proxyn kautta. Annotaatio aktivoituu vain, kun kutsu saapuu beaniin ulkoa. Jos menetelmä kutsuu toista välimuistitettua menetelmää this-viitteen kautta, kutsu ohittaa proxyn ja välimuistitus jää huomaamatta tekemättä.
- Siirtäkää välimuistitettu menetelmä erilliseen beaniin tai
- injektoikaa viittaus olioon itseensä tai käyttäkää
AopContext.currentProxy()-metodia
Tämä on sama proxyn rajoitus, jonka näette myös @Transactional-annotaation yhteydessä.
@Service
public class CatalogService {
public List<Book> report() {
// BUG: internal call -> proxy bypassed, NOT cached
return List.of(findByIsbn("123"));
}
@Cacheable("books")
public Book findByIsbn(String isbn) {
return repository.lookup(isbn);
}
}Pieni itsenäinen välimuistiesimerkki
Nähdäksenne välimuistituksen idean ilman Springiä seuraavassa on tavallinen Java-ohjelma, joka muistaa tulokset Map-rakenteeseen — juuri tämän @Cacheable automatisoi puolestanne. Suorittakaa ohjelma ja huomatkaa, että toinen kutsu palautuu välittömästi, koska se osuu välimuistiin.
import java.util.HashMap;
import java.util.Map;
public class Main {
static Map<String, String> cache = new HashMap<>();
static String findByIsbn(String isbn) {
if (cache.containsKey(isbn)) {
return cache.get(isbn) + " (from cache)";
}
try { Thread.sleep(200); } catch (InterruptedException e) {}
String book = "Book-" + isbn;
cache.put(isbn, book);
return book + " (computed)";
}
public static void main(String[] args) {
System.out.println(findByIsbn("123"));
System.out.println(findByIsbn("123"));
}
}Pikatarkistus
Käytössänne on updateBook(Book book)-menetelmä, jonka on aina tallennettava kirja tietokantaan ja päivitettävä välimuisti, jotta myöhemmät haut näkevät uudet tiedot. Mikä annotaatio on oikea?
Kertaus
Opitte Springin Cache Abstraction -välimuistabstraktion ja sen kolme keskeistä annotaatiota:
- @EnableCaching ottaa toiminnon käyttöön; sitä tukee
CacheManager(oletuksena muistinsisäinen, myöhemmin Caffeine tai Redis). - @Cacheable päättää suorituksen heti osuman yhteydessä — ihanteellinen lukuihin. Sen toimintaa voi säätää attribuuteilla
key,conditionjaunless. - @CachePut suoritetaan aina ja sen jälkeen välimuisti päivitetään — ihanteellinen kirjoituksiin.
- @CacheEvict poistaa merkintöjä (yhden avaimen tai
allEntries-asetuksen avulla) ja voi toimia valinnaisesti ennen kutsuabeforeInvocation-asetuksella. - Ryhmitelkää operaatiot @Caching-annotaatiolla ja varokaa self-invocation-proxyn sudenkuoppaa.
Tuloksena on deklaratiivisesti määritetty välimuistitus, joka ei kosketa liiketoimintalogiikkaa.
Opi Java tekoälytuutorin avulla — ilmaiseksi
Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.
- Kurssit
- 21
- Oppitunnit
- 84
Usein kysytyt kysymykset
Onko oppitunti ”Spring Cache -abstraktion perusteet” ilmainen?
Kyllä — voit lukea täällä verkossa kokonaan ilmaiseksi mitkä tahansa Spring Boot 4:n kattava opas-oppimispolun 3 oppituntia, myös oppitunnin “Spring Cache -abstraktion perusteet”. Sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä interaktiiviset harjoitukset sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Spring Boot 4:n kattava opas-kurssilla on yhteensä 4 oppituntia.
Mitä opin oppitunnilla ”Spring Cache -abstraktion perusteet”?
Lisätkää välimuistitus koskematta liiketoimintalogiikkaan käyttämällä @Cacheable-, @CachePut- ja @CacheEvict-annotaatioita. Harjoittelet Spring Boot 4:n kattava opas-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.
Tarvitsenko kokemusta aloittaakseni Spring Boot 4:n kattava opas-opiskelun?
Aiempi kokemus ei ole tarpeen. CoddyKitin Spring Boot 4:n kattava opas-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 1/4.
Kuinka kauan ”Spring Cache -abstraktion perusteet”-oppitunnin suorittaminen kestää?
Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.
Voinko kirjoittaa ja suorittaa koodia tällä Spring Boot 4:n kattava opas-oppitunnilla?
Kyllä. Jokainen Spring Boot 4:n kattava opas-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.
Kaikki tämän kurssin oppitunnit
- Spring Cache -abstraktion perusteet
- Muistinsisäinen välimuistitus ja Caffeinen hienosäätö
- Hajautettu välimuistitus Redisillä ja TTL-arvoilla
- Välimuistin stampede-ilmiö, mitätöinti ja johdonmukaisuus