{"id":4129,"date":"2018-04-06T22:10:44","date_gmt":"2018-04-06T20:10:44","guid":{"rendered":"http:\/\/www.tutego.de\/blog\/javainsel\/?p=4129"},"modified":"2018-04-06T22:10:44","modified_gmt":"2018-04-06T20:10:44","slug":"caching-in-spring-boot-nutzen","status":"publish","type":"post","link":"https:\/\/www.tutego.de\/blog\/javainsel\/2018\/04\/caching-in-spring-boot-nutzen\/","title":{"rendered":"Caching in Spring Boot nutzen"},"content":{"rendered":"<div class=\"sect2 data-line-3\">\n<h3 id=\"trueoptimierung_durch_caching\">Optimierung durch Caching<\/h3>\n<div class=\"paragraph data-line-5\">\n<p>Bei Methoden, die idempotent sind, also zu einem Parameter immer den gleichen Wert liefern, kann Spring einen Cache zur Optimierung einsetzen.<\/p>\n<\/div>\n<div class=\"ulist data-line-7\">\n<ul>\n<li>Im Grunde ist der Cache ein Assoziativspeicher, der die Methodenparameter als Schl\u00fcssel nutzt.<\/li>\n<\/ul>\n<\/div>\n<div class=\"paragraph data-line-9\">\n<p>Beispiele:<\/p>\n<\/div>\n<div class=\"ulist data-line-11\">\n<ul>\n<li>Berechnen einer Pr\u00fcfsumme<\/li>\n<li>Dateiinhalt<\/li>\n<li>DNS-Cache<\/li>\n<\/ul>\n<\/div>\n<div class=\"paragraph data-line-15\">\n<p>Achtung: Gewisse Cache-Inhalte k\u00f6nnen nach einer Zeit ung\u00fcltig werden.<\/p>\n<\/div>\n<\/div>\n<div class=\"sect2 data-line-18\">\n<h3 id=\"truecaching_in_spring\">Caching in Spring<\/h3>\n<div class=\"paragraph data-line-20\">\n<p>Um das Caching zu aktivieren annotiert man<\/p>\n<\/div>\n<div class=\"olist arabic data-line-22\">\n<ol class=\"arabic\">\n<li>eine <code>@Configuration<\/code> mit <code>@EnableCaching<\/code><\/li>\n<li>eine <code>public<\/code> (!!!) Methode mit <code>@Cacheable<\/code> und vergibt einen Cache-Namen.<\/li>\n<\/ol>\n<\/div>\n<\/div>\n<div class=\"sect2 data-line-27\">\n<h3 id=\"true_cacheable_beispiel_1_2\">@Cacheable-Beispiel (1\/2)<\/h3>\n<div class=\"listingblock data-line-30\">\n<div class=\"content\">\n<pre class=\"highlightjs highlight\"><code class=\"language-java hljs\" data-lang=\"java\"><span class=\"hljs-annotation\">@Component<\/span>\r\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Hash<\/span> <\/span>{\r\n\r\n  <span class=\"hljs-annotation\">@Cacheable<\/span>( <span class=\"hljs-string\">\"md5\"<\/span> )\r\n  <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">byte<\/span>[] md5( String text ) {\r\n\r\n    System.out.println( <span class=\"hljs-string\">\"hash: \"<\/span> + text );\r\n    <span class=\"hljs-keyword\">try<\/span> {\r\n      MessageDigest md = MessageDigest.getInstance( <span class=\"hljs-string\">\"MD5\"<\/span> );\r\n      <span class=\"hljs-keyword\">return<\/span> md.digest( text.getBytes( StandardCharsets.UTF_8 ) );\r\n    }\r\n    <span class=\"hljs-keyword\">catch<\/span> ( NoSuchAlgorithmException e ) {\r\n      <span class=\"hljs-keyword\">throw<\/span> <span class=\"hljs-keyword\">new<\/span> IllegalStateException( e );\r\n    }\r\n  }\r\n}<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"sect2 data-line-50\">\n<h3 id=\"true_cacheable_beispiel_2_2\">@Cacheable-Beispiel (2\/2)<\/h3>\n<div class=\"paragraph data-line-52\">\n<p>Wir k\u00f6nnen <code>Hash<\/code> injizieren<\/p>\n<\/div>\n<div class=\"listingblock data-line-55\">\n<div class=\"content\">\n<pre class=\"highlightjs highlight\"><code class=\"language-java hljs\" data-lang=\"java\"><span class=\"hljs-annotation\">@Autowired<\/span>\r\nHash hash;<\/code><\/pre>\n<\/div>\n<\/div>\n<div class=\"paragraph data-line-60\">\n<p>und nutzen<\/p>\n<\/div>\n<div class=\"listingblock data-line-63\">\n<div class=\"content\">\n<pre class=\"highlightjs highlight\"><code class=\"language-java hljs\" data-lang=\"java\"><span class=\"hljs-keyword\">byte<\/span>[] md5_1 = hash.md5( <span class=\"hljs-string\">\"tutego\"<\/span> );\r\n<span class=\"hljs-keyword\">byte<\/span>[] md5_2 = hash.md5( <span class=\"hljs-string\">\"tutego\"<\/span> );\r\nSystem.out.println( Arrays.equals( md5_1, md5_2 ) ); <span class=\"hljs-comment\">\/\/ true<\/span>\r\n\r\nSystem.out.println( hash.getClass() ); <span class=\"hljs-comment\">\/\/ com.tutego.boot.basic.Hash$$EnhancerBySpringCGLIB$$4548965<\/span><\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"sect2 data-line-72\">\n<h3 id=\"trueausblick_1_2\">Ausblick (1\/2)<\/h3>\n<div class=\"ulist data-line-74\">\n<ul>\n<li>Spring generiert den Schl\u00fcssel zum Cache aus den Argumente. Man kann kann eigene <code>KeyGenerator<\/code> en verwenden.<\/li>\n<li>Mit der SpEL lassen sich von Anfrageobejkte zum Beispiel die Schl\u00fcssel erfragen, etwa so <code>@Cacheable(cacheNames=\"books\", key=\"#isbn.rawNumber\")<\/code> .<\/li>\n<li>Unter Umst\u00e4nden sollen gro\u00dfe Objekte nicht in den Cache, hier kann man eine Bedingung angeben: <code>@Cacheable(cacheNames=\"book\", condition=\"#name.length() &lt; 32\")<\/code><\/li>\n<li>Ist eine Methode mit <code>@CachePut<\/code> annotiert, kann man den Cache selbst f\u00fcllen, bzw. Werte \u00fcberschreiben.<\/li>\n<li>Ist eine Methode mit <code>@CacheEvict<\/code> annotiert, etwa <code>@CacheEvict(cacheNames=\"books\", allEntries=true) public void clear()<\/code> wird der Cache gel\u00f6scht.<\/li>\n<\/ul>\n<\/div>\n<\/div>\n<div class=\"sect2 data-line-85\">\n<h3 id=\"trueausblick_2_2\">Ausblick (2\/2)<\/h3>\n<div class=\"paragraph data-line-87\">\n<p>Das Spring Framework kann automatisch diverse Caching-Implementierung nutzen.<\/p>\n<\/div>\n<div class=\"ulist data-line-89\">\n<ul>\n<li>Standardm\u00e4\u00dfig ist es eine <code>ConcurrentHashMap<\/code>.<\/li>\n<li>Unterst\u00fctzt werden u.a.: EhCache 2.x, Hazelcast, Infinispan, Couchbase, Redis, Caffeine.<\/li>\n<li>Spring erkennt anhand des Eintrags im Klassenpfad, was gew\u00fcnscht ist.<\/li>\n<\/ul>\n<\/div>\n<div class=\"paragraph data-line-93\">\n<p>In der <em>application.[properties|yml]<\/em> lassen sich dann Dinge wie Lebensdauer, Gr\u00f6\u00dfe, etc. extern konfigurieren.<\/p>\n<\/div>\n<div class=\"ulist data-line-95\">\n<ul>\n<li>Beispiel mit Caffeine: <a class=\"bare\" href=\"https:\/\/memorynotfound.com\/spring-boot-caffeine-caching-example-configuration\/\">https:\/\/memorynotfound.com\/spring-boot-caffeine-caching-example-configuration\/<\/a><\/li>\n<\/ul>\n<\/div>\n<div class=\"paragraph data-line-98\">\n<p><a class=\"bare\" href=\"https:\/\/docs.spring.io\/spring\/docs\/5.0.4.RELEASE\/spring-framework-reference\/integration.html#cache\">https:\/\/docs.spring.io\/spring\/docs\/5.0.4.RELEASE\/spring-framework-reference\/integration.html#cache<\/a><\/p>\n<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>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\u00fcssel nutzt. Beispiele: Berechnen einer Pr\u00fcfsumme Dateiinhalt DNS-Cache Achtung: Gewisse Cache-Inhalte k\u00f6nnen nach einer Zeit ung\u00fcltig werden. Caching in Spring [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":"","_links_to":"","_links_to_target":""},"categories":[3],"tags":[],"class_list":["post-4129","post","type-post","status-publish","format-standard","hentry","category-spring"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/4129","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/comments?post=4129"}],"version-history":[{"count":1,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/4129\/revisions"}],"predecessor-version":[{"id":4130,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/4129\/revisions\/4130"}],"wp:attachment":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/media?parent=4129"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/categories?post=4129"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/tags?post=4129"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}