拦截器:动态代理不好理解,所以开发人员就设计了一个拦截器让开发者使用,简化开发(但是实现好难,问题是我还得学。啊啊啊啊啊啊)
定义一个我自己拦截器,目的是加注释,
-
before返回boolean值,他在真实对象之前调用,当返回true时,则反射真是对象的 方法 ,返回false时,调用around方法
-
在反射真实对象方法或者around之后,调用after
package test.interseptor;
import java.lang.reflect.Method;
import org.aopalliance.intercept.Interceptor;
public class MyInterceptor implements Interceptor{
public boolean Before(Object proxy, Method method, Object[] args){
System.out.println("反射方法前逻辑");
return false;
}
public void around(Object proxy, Method method, Object[] args){
System.out.println("取代了被代理的方法");
}
public void after(Object proxy, Method method, Object[] args){
System.out.println("反射方法后的逻辑");
}
}
package test.interseptor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import org.aopalliance.intercept.Interceptor;
public class InterceptorJDKproxy implements InvocationHandler{
private Object target;//真实对象
private String interceptorClass = null;//拦截器全限定名
public InterceptorJDKproxy(Object target,String interceptorClass) {
this.target=target;
this.interceptorClass = interceptorClass;
}
/*
* 绑定委托对象,并返回一个【代理占位】
*
* @param target 真实对象
* return 代理对象
* */
public static Object bind(Object target,String interceptorClass) {
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(), new InterceptorJDKproxy(target, interceptorClass));
}
/*
* 通过代理对象,调用放啊,首先进入这个invoke方法
* @param proxy 代理对象
* @param method 当前调度方法
* @param args 当前方法参数
*
* */
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
if(interceptorClass==null){
//假如没有拦截器则直接返回方法
return method.invoke(target, args);
}
System.out.println("拦截器在这呢"+interceptorClass);
Object result = null;
//如果有拦截器,那么就通过反射创建拦截器
//这个 MyInterceptor 应该写接口的名字,但是吧,我的那个ssm炸了,继承之后没有参数,我就只好这么写了,Mark下,省的我忘了
MyInterceptor interceptor = (MyInterceptor) Class.forName(interceptorClass).newInstance();
if(interceptor.Before(proxy, method, args)){
//反射原有对象
result= method.invoke(target, args);
}
else{
//如果是false,就执行round方法
interceptor.around(proxy, method, args);
}
interceptor.after(proxy, method, args);
return result;
}
}
package test.interseptor;
import test.jdkproxy.HellowWord;
import test.jdkproxy.HellowWordImpl;
public class TestMyInterceptor {
public static void main(String[] args) {
HellowWordImpl proxy = (HellowWordImpl) InterceptorJDKproxy.bind(new HellowWord(),
"test.interseptor.MyInterceptor");
proxy.SayHellowWord();
}
}
---------------------------------------------------------------------------------------分割线,输出结果-----------------------------------------------------------------------------------------------------------------
反射方法前逻辑
取代了被代理的方法
反射方法后的逻辑
拦截器大概懂了,无非就是通过接口实现了一个有三个类的对象,然后通过if语句进行逻辑判断,然后还是通过添加到之前的jdk或者CGlib里的invoke或者interceptor方法来执行并不难理解,看看书上的说明,这个拦截器的执行步骤:
-
在bind中使用jdk动态代理绑定了一个对象,然后返回代理对象
-
如果没有设置拦截器,则直接返回对象的方法,否则执行第三部
-
通过反射生成拦截器,并准备使用
-
调用拦截器的before方法,如果为true,反射原来的方法,否则,运行拦截器的around方法
-
最后调用after方法,
-
返回
拦截器的执行过程
还有个责任链模式,袋盖就是多个拦截器一起用,拦截器的话,before的执行顺序是321,after的执行顺序是123