Thomas Darimont
Erfahrenes Mitglied
Hallo,
dieser Beitrag erklärt das Verhaltensmuster: Interceptor
Ausgabe:
Gruß Tom
dieser Beitrag erklärt das Verhaltensmuster: Interceptor
Java:
package de.tutorials.design.patterns.behavioral;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class InterceptorExample {
public static void main(String[] args) {
Dispatcher dispatcher = new DispatcherImpl(new TracingInterceptor(), new SecurityInterceptor());
Service service = dispatcher.newProxy(Service.class, new ServiceImpl());
System.out.println("Result: " + service.businessMethod("foo"));
}
static interface Service {
String businessMethod(String arg);
}
static class ServiceImpl implements Service {
@Override
public String businessMethod(String arg) {
System.out.println("Code execution");
return "#" + arg + "#";
}
}
static interface Interceptor {
Object intercept(MethodInvocation mi);
}
static class TracingInterceptor implements Interceptor {
@Override
public Object intercept(MethodInvocation mi) {
System.out.println("TRACE Before: " + mi.getMethod());
try {
return mi.proceed();
} finally {
System.out.println("TRACE After: " + mi.getMethod());
}
}
}
static class SecurityInterceptor implements Interceptor {
@Override
public Object intercept(MethodInvocation mi) {
System.out.println("SECURITY Before " + mi.getMethod());
try {
return mi.proceed();
} finally {
System.out.println("SECURITY After " + mi.getMethod());
}
}
}
static interface Dispatcher {
<INF, IMPL extends INF> INF newProxy(Class<INF> infType, IMPL impl);
}
static class DispatcherImpl implements Dispatcher {
private final static Method interceptMethod;
static{
try {
interceptMethod = Interceptor.class.getDeclaredMethod("intercept", MethodInvocation.class);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private final Interceptor[] interceptors;
public DispatcherImpl(Interceptor... interceptors) {
this.interceptors = interceptors;
}
public <INF, IMPL extends INF> INF newProxy(Class<INF> infType, IMPL impl) {
return infType.cast(Proxy.newProxyInstance(infType.getClassLoader(), new Class[] { infType }, createInterceptorHandler(impl)));
}
private InvocationHandler createInterceptorHandler(final Object target) {
return new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
MethodInvocation mi = wrapInterceptorsAround(new MethodInvocation(target, method, args));
return mi.proceed();
}
};
}
private MethodInvocation wrapInterceptorsAround(MethodInvocation mi) {
MethodInvocation currentMethodInvocation = mi;
for (int i = interceptors.length - 1; i >= 0; i--) {
currentMethodInvocation = new MethodInvocation(interceptors[i],interceptMethod,new Object[] { currentMethodInvocation });
}
return currentMethodInvocation;
}
}
static class MethodInvocation {
private final Object target;
private final Method method;
private final Object[] args;
private Object result;
public MethodInvocation(Object target, Method method, Object[] args) {
this.target = target;
this.method = method;
this.args = args;
}
public Object proceed() {
try {
return method.invoke(target, args);
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
public Object getResult() {
return result;
}
public void setResult(Object result) {
this.result = result;
}
public Object getTarget() {
return target;
}
public Method getMethod() {
return method;
}
public Object[] getArgs() {
return args;
}
}
}
Ausgabe:
Code:
TRACE Before: public abstract java.lang.Object de.tutorials.design.patterns.behavioral.InterceptorExample$Interceptor.intercept(de.tutorials.design.patterns.behavioral.InterceptorExample$MethodInvocation)
SECURITY Before public abstract java.lang.String de.tutorials.design.patterns.behavioral.InterceptorExample$Service.businessMethod(java.lang.String)
Code execution
SECURITY After public abstract java.lang.String de.tutorials.design.patterns.behavioral.InterceptorExample$Service.businessMethod(java.lang.String)
TRACE After: public abstract java.lang.Object de.tutorials.design.patterns.behavioral.InterceptorExample$Interceptor.intercept(de.tutorials.design.patterns.behavioral.InterceptorExample$MethodInvocation)
Result: #foo#
Gruß Tom