代理模式在Spring中主要体现在Spring框架的核心功能之一的AOP,通过AOP将切面通知织入到指定的切点位置,简单一点就是可以是现在某个方法运行前后添加指定的功能。下面简单实现一个将拦截器织入指定的方法上。
1 拦截器接口
public interface Intercepter {
boolean before();
void after();
Object around(Invocation invocation) throws InvocationTargetException, IllegalAccessException;
void afterReturning();
void afterThrowing();
boolean userAround();
}
2 拦截器实现类
public class MyIntercepter implements Intercepter {
@Override
public boolean before() {
System.out.println("before ===========");
return true;
}
@Override
public void after() {
System.out.println("after ===========");
}
@Override
public Object around(Invocation invocation) throws InvocationTargetException, IllegalAccessException {
System.out.println("around before ============");
Object obj = invocation.proceed();
System.out.println("around after ============");
return obj;
}
@Override
public void afterReturning() {
System.out.println("afterReturning ============");
}
@Override
public void afterThrowing() {
System.out.println("afterThrowing ============");
}
@Override
public boolean userAround() {
return true;
}
}
3 自定义调用工具
public class Invocation {
private Object[] params;
private Object target;
private Method method;
public Invocation(Object[] params, Object target, Method method) {
this.params = params;
this.target = target;
this.method = method;
}
public Object proceed() throws InvocationTargetException, IllegalAccessException {
return method.invoke(target, params);
}
}
4 自定义代理对象(类似Spring中的ProxyFactory生成代理类,将Interceptor织入)
public class ProxyBean implements InvocationHandler {
private Object target;
private Intercepter intercepter;
public static Object getProxyBean(Object target, Intercepter intercepter) {
ProxyBean proxyBean = new ProxyBean();
proxyBean.target = target;
proxyBean.intercepter = intercepter;
Object proxy = Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), proxyBean);
return proxy;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
boolean exceptionFlag = false;
Invocation invocation = new Invocation(args, target, method);
Object retObj = null;
try {
if(intercepter.before()) {
retObj = intercepter.around(invocation);
} else {
retObj = method.invoke(target, args);
}
} catch (Exception e) {
exceptionFlag = true;
}
intercepter.after();
if(exceptionFlag) {
intercepter.afterThrowing();
} else {
intercepter.afterReturning();
return retObj;
}
return null;
}
}
以上这个代理类类似
/**
*创建一个新的代理工厂,拥有需要代理的接口和织入的拦截器
*/
public ProxyFactory(Class<?> proxyInterface, Interceptor interceptor) {
addInterface(proxyInterface);
addAdvice(interceptor);
}
public Object getProxy() {
return createAopProxy().getProxy();
}
调用代理类间接调用接口方法,就能实现在指定方法前后织入相应的拦截器功能。关于Spring AOP功能的具体实现后面再分享。