Java AOP with aopalliance -- method interceptors and custom annotations
Spring Interview Questions and Answers Q1 - Q14 are FAQs
Step 1: What is AOP Alliance?
AOP Alliance intends to facilitate and standardize the use of AOP to enhance existing middle ware environments (such as JEE), or development environements (e.g. Eclipse, NetBeans). The AOP Alliance also aims to ensure interoperability between Java/JEE AOP implementations to build a larger AOP community.
AOP Alliance is a set of interfaces that multiple frameworks implement, including both Guice and Spring.
<groupId>aopalliance</groupId> <artifactId>aopalliance</artifactId> <version>1.0</version>
Q. Why use AOP Alliance in Spring?
Spring AOP can be used together with AOP Alliance MethodInterceptors. AOP Alliance compliant interceptors foster interoperability with other AOP frameworks such as Google Guice. Spring can be used with AspectJ as well, which has annotation syntax that is concise and expressive.
Step 2: Define a custom annotation so taht a method that is annotated with this custom annotation can be retried based on supplied values like attempts,interval, etc.
package com.interceptor.retry; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Inherited public @interface Retry { int attempts() default 3; int interval() default 3000; boolean nonNullReturn() default true; Class<? extends Throwable> exception() default RetryException.class; //static inner class static class RetryException extends Throwable { private static final long serialVersionUID = 1L; // for serialization private RetryException() {} } }
Step 3: Java method interceptor using the aop alliance jar to implement retry logic as a cross cutting concern. Mthods annotated with @Retry will be retried after waiting for the supplied interval.
package com.interceptor.retry; import java.lang.reflect.Method; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; public class RetryMethodInterceptor implements MethodInterceptor { @Override public Object invoke (MethodInvocation invocation) throws Throwable { // Method annotatedMethod = invocation.getMethod(); Method objectMethod = invocation.getThis().getClass() .getMethod(annotatedMethod.getName(), annotatedMethod.getParameterTypes()); Retry retry = objectMethod.getAnnotation(Retry.class); Throwable throwable = null; Object result = null; int attempt = 0; String method = String.format("%s.%s", invocation.getMethod().getDeclaringClass() .getName(), invocation.getMethod().getName()); System.out.println("Invoking {}" + method); do { attempt++; try { result = invocation.proceed(); if (result == null && retry.nonNullReturn()) { throw new RuntimeException(String.format("Non-null return expected for %s", method)); } System.out.println("Completed {}" + method); return result; } catch (Throwable retryThrowable) { throwable = retryThrowable; try { Thread.sleep(retry.interval()); } catch (InterruptedException e) { System.out.println("Retry wait interrupted"); } } } while (attempt < retry.attempts()); //if reached here, all retires have failed System.out.println(String.format("Failed invoking %s", method)); throw retry.exception().getConstructor(Throwable.class).newInstance(throwable); } }
The above example is frequently used in enterprise applications to solve issues relating to
1. Deadlock retry.
2. Service retry.
Labels: annotation, AOP
0 Comments:
Post a Comment
Subscribe to Post Comments [Atom]
<< Home