{"id":4131,"date":"2018-04-06T22:12:53","date_gmt":"2018-04-06T20:12:53","guid":{"rendered":"http:\/\/www.tutego.de\/blog\/javainsel\/?p=4131"},"modified":"2018-04-06T22:12:53","modified_gmt":"2018-04-06T20:12:53","slug":"spring-retry-projekt","status":"publish","type":"post","link":"https:\/\/www.tutego.de\/blog\/javainsel\/2018\/04\/spring-retry-projekt\/","title":{"rendered":"Spring Retry"},"content":{"rendered":"<div class=\"sect2 data-line-3\">\n<h3 id=\"truedas_spring_retry_projekt\">Das Spring Retry Projekt<\/h3>\n<div class=\"paragraph data-line-5\">\n<p><strong>Spring Retry<\/strong> ist ein Zusatzprojekt (<a class=\"bare\" href=\"https:\/\/github.com\/spring-projects\/spring-retry\">https:\/\/github.com\/spring-projects\/spring-retry<\/a>), um Codebl\u00f6cke wiederholt auszuf\u00fchren, wenn sie zu einem Fehler f\u00fchren.<\/p>\n<\/div>\n<div class=\"ulist data-line-7\">\n<ul>\n<li>Das ist n\u00fctzlich beim Ansprechen von Remote-Diensten, die tempor\u00e4r nicht verf\u00fcgbar sein k\u00f6nnen.<\/li>\n<\/ul>\n<\/div>\n<div class=\"paragraph data-line-9\">\n<p>Als erstes m\u00fcssen zwei Dependencies in unsere POM:<\/p>\n<\/div>\n<div class=\"listingblock data-line-12\">\n<div class=\"content\">\n<pre class=\"highlightjs highlight\"><code class=\"language-xml hljs\" data-lang=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-title\">dependency<\/span>&gt;<\/span>\r\n\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-title\">groupId<\/span>&gt;<\/span>org.springframework.retry<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-title\">groupId<\/span>&gt;<\/span>\r\n\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-title\">artifactId<\/span>&gt;<\/span>spring-retry<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-title\">artifactId<\/span>&gt;<\/span>\r\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-title\">dependency<\/span>&gt;<\/span>\r\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-title\">dependency<\/span>&gt;<\/span>\r\n\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-title\">groupId<\/span>&gt;<\/span>org.springframework<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-title\">groupId<\/span>&gt;<\/span>\r\n\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-title\">artifactId<\/span>&gt;<\/span>spring-aspects<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-title\">artifactId<\/span>&gt;<\/span>\r\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-title\">dependency<\/span>&gt;<\/span><\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"sect2 data-line-24\">\n<h3 id=\"true_retryable\">@Retryable<\/h3>\n<div class=\"paragraph data-line-26\">\n<p>Schreiben wir eine Bean, die zwei Anl\u00e4ufe braucht, eine Operation durchzuf\u00fchren.<\/p>\n<\/div>\n<div class=\"listingblock data-line-29\">\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\">Achiever<\/span> <\/span>{\r\n\r\n  <span class=\"hljs-keyword\">int<\/span> tries = <span class=\"hljs-number\">1<\/span>;\r\n\r\n  <span class=\"hljs-annotation\">@Retryable<\/span>   <i class=\"conum\" data-value=\"1\"><\/i>\r\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">tryIt<\/span><span class=\"hljs-params\">()<\/span> <\/span>{   <i class=\"conum\" data-value=\"2\"><\/i>\r\n\r\n    System.out.println( <span class=\"hljs-string\">\"Runde \"<\/span> + tries );\r\n    tries++;\r\n\r\n    <span class=\"hljs-keyword\">if<\/span> ( tries != <span class=\"hljs-number\">3<\/span> )\r\n      <span class=\"hljs-keyword\">throw<\/span> <span class=\"hljs-keyword\">new<\/span> IllegalStateException( <span class=\"hljs-string\">\"Runde nicht 3\"<\/span> );\r\n\r\n    <span class=\"hljs-keyword\">return<\/span> tries;\r\n  }\r\n}<\/code><\/pre>\n<\/div>\n<\/div>\n<div class=\"colist arabic data-line-48\">\n<table>\n<tbody>\n<tr>\n<td><\/td>\n<td><code>Retryable<\/code> dr\u00fcckt aus, das eine Operation bei Ausnahmen automatisch neu aufgerufen werden soll.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>Die Methoden k\u00f6nnen eine R\u00fcckgabe haben, oder auch keine.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<div class=\"sect2 data-line-52\">\n<h3 id=\"true_enableretry\">@EnableRetry<\/h3>\n<div class=\"paragraph data-line-54\">\n<p>Damit Spring f\u00fcr die annotierten Methoden einen Proxy baut, m\u00fcssen wir eine <code>@Configuration<\/code> mit <code>@EnableRetry<\/code> annotieren.<\/p>\n<\/div>\n<div class=\"paragraph data-line-56\">\n<p>Wir k\u00f6nnen nun den <code>Achiever<\/code> injizieren:<\/p>\n<\/div>\n<div class=\"listingblock data-line-59\">\n<div class=\"content\">\n<pre class=\"highlightjs highlight\"><code class=\"language-java hljs\" data-lang=\"java\"><span class=\"hljs-annotation\">@Autowired<\/span> Achiever archiever;<\/code><\/pre>\n<\/div>\n<\/div>\n<div class=\"paragraph data-line-63\">\n<p>Und die Methode ausf\u00fchren:<\/p>\n<\/div>\n<div class=\"listingblock data-line-66\">\n<div class=\"content\">\n<pre class=\"highlightjs highlight\"><code class=\"language-java hljs\" data-lang=\"java\">System.out.println( <span class=\"hljs-string\">\"Vor dem Aufruf\"<\/span> );\r\n<span class=\"hljs-keyword\">int<\/span> i = archiever.tryIt();\r\nSystem.out.println( <span class=\"hljs-string\">\"Nach dem Aufruf ist i=\"<\/span> + i );<\/code><\/pre>\n<\/div>\n<\/div>\n<div class=\"paragraph data-line-72\">\n<p>Auf der Konsole erscheint keine Exception. Nur:<\/p>\n<\/div>\n<div class=\"listingblock data-line-74\">\n<div class=\"content\">\n<pre>Vor dem Aufruf\r\nRunde 1\r\nRunde 2\r\nNach dem Aufruf<\/pre>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"sect2 data-line-82\">\n<h3 id=\"trueder_annotationsty_retryable\">Der Annotationsty Retryable<\/h3>\n<div class=\"listingblock data-line-85\">\n<div class=\"content\">\n<pre class=\"highlightjs highlight\"><code class=\"language-java hljs\" data-lang=\"java\"><span class=\"hljs-annotation\">@Target<\/span>({ ElementType.METHOD, ElementType.TYPE })\r\n<span class=\"hljs-annotation\">@Retention<\/span>(RetentionPolicy.RUNTIME)\r\n<span class=\"hljs-annotation\">@Documented<\/span>\r\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-annotation\">@interface<\/span> Retryable {\r\n\t<span class=\"hljs-function\">String <span class=\"hljs-title\">interceptor<\/span><span class=\"hljs-params\">()<\/span> <span class=\"hljs-keyword\">default<\/span> \"\"<\/span>;\r\n\tClass&lt;? extends Throwable&gt;[] value() <span class=\"hljs-keyword\">default<\/span> {};\r\n\tClass&lt;? extends Throwable&gt;[] include() <span class=\"hljs-keyword\">default<\/span> {};\r\n\tClass&lt;? extends Throwable&gt;[] exclude() <span class=\"hljs-keyword\">default<\/span> {};\r\n\t<span class=\"hljs-function\">String <span class=\"hljs-title\">label<\/span><span class=\"hljs-params\">()<\/span> <span class=\"hljs-keyword\">default<\/span> \"\"<\/span>;\r\n\t<span class=\"hljs-function\"><span class=\"hljs-keyword\">boolean<\/span> <span class=\"hljs-title\">stateful<\/span><span class=\"hljs-params\">()<\/span> <span class=\"hljs-keyword\">default<\/span> <span class=\"hljs-keyword\">false<\/span><\/span>;\r\n\t<span class=\"hljs-function\"><span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">maxAttempts<\/span><span class=\"hljs-params\">()<\/span> <span class=\"hljs-keyword\">default<\/span> 3<\/span>;              <i class=\"conum\" data-value=\"1\"><\/i>\r\n\t<span class=\"hljs-function\">String <span class=\"hljs-title\">maxAttemptsExpression<\/span><span class=\"hljs-params\">()<\/span> <span class=\"hljs-keyword\">default<\/span> \"\"<\/span>;\r\n\t<span class=\"hljs-function\">Backoff <span class=\"hljs-title\">backoff<\/span><span class=\"hljs-params\">()<\/span> <span class=\"hljs-keyword\">default<\/span> @<span class=\"hljs-title\">Backoff<\/span><span class=\"hljs-params\">()<\/span><\/span>;\r\n\t<span class=\"hljs-function\">String <span class=\"hljs-title\">exceptionExpression<\/span><span class=\"hljs-params\">()<\/span> <span class=\"hljs-keyword\">default<\/span> \"\"<\/span>;\r\n}<\/code><\/pre>\n<\/div>\n<\/div>\n<div class=\"colist arabic data-line-102\">\n<table>\n<tbody>\n<tr>\n<td><\/td>\n<td>Die Anzahl der Wiederholungen ist nicht unendlich, Spring stoppt standardm\u00e4\u00dfig bei 3.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<div class=\"sect2 data-line-105\">\n<h3 id=\"trueausblick\">Ausblick<\/h3>\n<div class=\"paragraph data-line-107\">\n<p>Die Dokumentation unter <a class=\"bare\" href=\"https:\/\/github.com\/spring-projects\/spring-retry\">https:\/\/github.com\/spring-projects\/spring-retry<\/a> zeit weitere M\u00f6glichkeiten auf. Ein zus\u00e4tzliches Beispiel:<\/p>\n<\/div>\n<div class=\"listingblock data-line-110\">\n<div class=\"content\">\n<pre class=\"highlightjs highlight\"><code class=\"language-java hljs\" data-lang=\"java\"><span class=\"hljs-annotation\">@Retryable<\/span>\r\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">tryIO<\/span><span class=\"hljs-params\">()<\/span> <span class=\"hljs-keyword\">throws<\/span> IOException <\/span>{\r\n  <span class=\"hljs-keyword\">throw<\/span> <span class=\"hljs-keyword\">new<\/span> IOException( LocalTime.now().toString() );\r\n}\r\n\r\n<span class=\"hljs-annotation\">@Recover<\/span>  <i class=\"conum\" data-value=\"1\"><\/i>\r\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">recover<\/span><span class=\"hljs-params\">( IOException e )<\/span> <\/span>{\r\n  System.err.println( <span class=\"hljs-string\">\"Aarrrrg: \"<\/span> + e );\r\n}<\/code><\/pre>\n<\/div>\n<\/div>\n<div class=\"colist arabic data-line-122\">\n<table>\n<tbody>\n<tr>\n<td><\/td>\n<td>Die mit <code>@Recover<\/code> annotierte Methode wird am Ende einer nicht erfolgreichen Aufrufkette aufgerufen.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Das Spring Retry Projekt Spring Retry ist ein Zusatzprojekt (https:\/\/github.com\/spring-projects\/spring-retry), um Codebl\u00f6cke wiederholt auszuf\u00fchren, wenn sie zu einem Fehler f\u00fchren. Das ist n\u00fctzlich beim Ansprechen von Remote-Diensten, die tempor\u00e4r nicht verf\u00fcgbar sein k\u00f6nnen. Als erstes m\u00fcssen zwei Dependencies in unsere POM: &lt;dependency&gt; &lt;groupId&gt;org.springframework.retry&lt;\/groupId&gt; &lt;artifactId&gt;spring-retry&lt;\/artifactId&gt; &lt;\/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;org.springframework&lt;\/groupId&gt; &lt;artifactId&gt;spring-aspects&lt;\/artifactId&gt; &lt;\/dependency&gt; @Retryable Schreiben wir eine Bean, die [&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-4131","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\/4131","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=4131"}],"version-history":[{"count":1,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/4131\/revisions"}],"predecessor-version":[{"id":4132,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/4131\/revisions\/4132"}],"wp:attachment":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/media?parent=4131"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/categories?post=4131"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/tags?post=4131"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}