Skip to content

Instantly share code, notes, and snippets.

@gabfssilva
Last active August 29, 2015 14:17
Show Gist options
  • Save gabfssilva/e21cf0dfbebe9f0e0312 to your computer and use it in GitHub Desktop.
Save gabfssilva/e21cf0dfbebe9f0e0312 to your computer and use it in GitHub Desktop.
package interceptor;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* @author Gabriel Francisco - [email protected]
*/
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface Interceptor {
Class<?> interceptorClazz();
}
package interceptor;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* @author Gabriel Francisco - [email protected]
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface After {
}
package interceptor;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* @author Gabriel Francisco - [email protected]
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface Before {
}
package interceptor;
import java.lang.reflect.Method;
/**
* @author Gabriel Francisco - [email protected]
*/
public class InvocationContext {
private Object target;
private Object result;
private Method method;
public InvocationContext(Object target, Method method) {
this.target = target;
this.method = method;
}
public InvocationContext(Object target, Object result, Method method) {
this.target = target;
this.result = result;
this.method = method;
}
public Object getTarget() {
return target;
}
public Method getMethod() {
return method;
}
public Object getResult() {
return result;
}
public void setResult(Object result) {
this.result = result;
}
}
package interceptor;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* @author Gabriel Francisco - [email protected]
*/
public class InterceptorInvocationHandler implements InvocationHandler {
private Object instance;
public InterceptorInvocationHandler(Object instance) {
this.instance = instance;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Interceptor interceptor = null;
for (Annotation annotation : instance.getClass().getDeclaredAnnotations()) {
if (annotation.annotationType().isAnnotationPresent(Interceptor.class)) {
interceptor = annotation.annotationType().getAnnotation(Interceptor.class);
}
}
if (interceptor == null) {
throw new IllegalArgumentException("There is no interceptor to invoke");
}
Object o = interceptor.interceptorClazz().newInstance();
Method[] methods = interceptor.interceptorClazz().getDeclaredMethods();
Method before = null;
Method after = null;
for (Method m : methods) {
if (m.isAnnotationPresent(Before.class)) {
before = m;
}
if (m.isAnnotationPresent(After.class)) {
after = m;
}
}
InvocationContext invocationContext = new InvocationContext(instance, method);
if (before != null) {
before.invoke(o, invocationContext);
}
invocationContext.setResult(method.invoke(instance, args));
if (after != null) {
after.invoke(o, invocationContext);
}
return invocationContext.getResult();
}
}
package interceptor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
/**
* @author Gabriel Francisco - [email protected]
*/
public class InterceptorProxy {
public static <T> T createProxy(Object instance, Class<?> interfaceClazz) {
InvocationHandler handler = new InterceptorInvocationHandler(instance);
return (T) Proxy.newProxyInstance(interfaceClazz.getClassLoader(), new Class[]{interfaceClazz}, handler);
}
}
//EXEMPLO
//EXEMPLO
//EXEMPLO
package sample;
import interceptor.Interceptor;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* @author Gabriel Francisco - [email protected]
*/
@Retention(RetentionPolicy.RUNTIME)
@Interceptor(interceptorClazz = LoggerInterceptor.class)
public @interface Logger {
}
package sample;
import interceptor.After;
import interceptor.Before;
import interceptor.InvocationContext;
/**
* @author Gabriel Francisco - [email protected]
*/
public class LoggerInterceptor {
@Before
public void before(InvocationContext invocationContext){
System.out.println("before method: " + invocationContext.getMethod().getName());
}
@After
public void after(InvocationContext invocationContext){
System.out.println("after method: " + invocationContext.getMethod().getName());
}
}
package sample;
/**
* @author Gabriel Francisco - [email protected]
*/
public interface SampleClass {
void doSomething();
}
package sample;
import interceptor.InterceptorProxy;
/**
* @author Gabriel Francisco - [email protected]
*/
@Logger
public class SampleClassImpl implements SampleClass {
@Override
public void doSomething(){
System.out.println("doSomething method!");
}
public static void main(String[] args) {
SampleClass sampleClass = new InterceptorProxy().createProxy(new SampleClassImpl(), SampleClass.class);
sampleClass.doSomething();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment