Optimierung durch Caching
Bei Methoden, die idempotent sind, also zu einem Parameter immer den gleichen Wert liefern, kann Spring einen Cache zur Optimierung einsetzen.
- Im Grunde ist der Cache ein Assoziativspeicher, der die Methodenparameter als Schlüssel nutzt.
Beispiele:
- Berechnen einer Prüfsumme
- Dateiinhalt
- DNS-Cache
Achtung: Gewisse Cache-Inhalte können nach einer Zeit ungültig werden.
Caching in Spring
Um das Caching zu aktivieren annotiert man
- eine
@Configuration
mit@EnableCaching
- eine
public
(!!!) Methode mit@Cacheable
und vergibt einen Cache-Namen.
@Cacheable-Beispiel (1/2)
@Component
class Hash {
@Cacheable( "md5" )
public byte[] md5( String text ) {
System.out.println( "hash: " + text );
try {
MessageDigest md = MessageDigest.getInstance( "MD5" );
return md.digest( text.getBytes( StandardCharsets.UTF_8 ) );
}
catch ( NoSuchAlgorithmException e ) {
throw new IllegalStateException( e );
}
}
}
@Cacheable-Beispiel (2/2)
Wir können Hash
injizieren
@Autowired
Hash hash;
und nutzen
byte[] md5_1 = hash.md5( "tutego" );
byte[] md5_2 = hash.md5( "tutego" );
System.out.println( Arrays.equals( md5_1, md5_2 ) ); // true
System.out.println( hash.getClass() ); // com.tutego.boot.basic.Hash$$EnhancerBySpringCGLIB$$4548965
Ausblick (1/2)
- Spring generiert den Schlüssel zum Cache aus den Argumente. Man kann kann eigene
KeyGenerator
en verwenden. - Mit der SpEL lassen sich von Anfrageobejkte zum Beispiel die Schlüssel erfragen, etwa so
@Cacheable(cacheNames="books", key="#isbn.rawNumber")
. - Unter Umständen sollen große Objekte nicht in den Cache, hier kann man eine Bedingung angeben:
@Cacheable(cacheNames="book", condition="#name.length() < 32")
- Ist eine Methode mit
@CachePut
annotiert, kann man den Cache selbst füllen, bzw. Werte überschreiben. - Ist eine Methode mit
@CacheEvict
annotiert, etwa@CacheEvict(cacheNames="books", allEntries=true) public void clear()
wird der Cache gelöscht.
Ausblick (2/2)
Das Spring Framework kann automatisch diverse Caching-Implementierung nutzen.
- Standardmäßig ist es eine
ConcurrentHashMap
. - Unterstützt werden u.a.: EhCache 2.x, Hazelcast, Infinispan, Couchbase, Redis, Caffeine.
- Spring erkennt anhand des Eintrags im Klassenpfad, was gewünscht ist.
In der application.[properties|yml] lassen sich dann Dinge wie Lebensdauer, Größe, etc. extern konfigurieren.
- Beispiel mit Caffeine: https://memorynotfound.com/spring-boot-caffeine-caching-example-configuration/