拦截器的作用
和动态代理一样,也可以在业务方法前后加入自己的逻辑,它就是基于动态代理实现的。但由于动态代理比较难以理解,于是设计一个拦截器接口供开发者使用。
拦截器的步骤
1.定义拦截器接口Interceptor
package test1;
import java.lang.reflect.Method;
public interface Interceptor {
//代理对象 真实对象 方法 方法参数
//在真实对象前调用,返回true则反射真实对象方法;false则调用around方法
public boolean before(Object proxy,Object target,Method method,Object[] args);
public void around(Object proxy,Object target,Method method,Object[] args);
//反射真实对象方法或者调用around方法后调用after方法
public void after(Object proxy,Object target,Method method,Object[] args);
}2.实现Interceptor接口
package test1;
import java.lang.reflect.Method;
public class MyInterceptor implements Interceptor{
@Override
public boolean before(Object proxy, Object target, Method method, Object[] args) {
// TODO Auto-generated method stub
System.out.println("反射方法前逻辑");
return false;//不反射被代理对象原有方法
}
@Override
public void around(Object proxy, Object target, Method method, Object[] args) {
// TODO Auto-generated method stub
System.out.println("取代了被代理对象的方法");
}
@Override
public void after(Object proxy, Object target, Method method, Object[] args) {
// TODO Auto-generated method stub
System.out.println("反射方法后逻辑");
}
}3.在JDK动态代理中使用拦截器
package test1;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class InterceptorJdkProxy implements InvocationHandler{
private Object target;//真实对象
private String interceptorClass;//拦截器全限定名
public InterceptorJdkProxy(Object target, String interceptorClass) {
// TODO Auto-generated constructor stub
this.target=target;
this.interceptorClass=interceptorClass;
}
/**
* 绑定委托对象并返回一个 代理占位
* @param target
* @param interceptorClass
* @return 代理对象占位
*/
public static Object bind(Object target,String interceptorClass) {
//取得代理对象
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InterceptorJdkProxy(target,interceptorClass));
}
@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);
}
Object result=null;
//通过反射生成拦截器
Interceptor interceptor=(Interceptor)Class.forName(interceptorClass).newInstance();
//调用前值方法
if(interceptor.before(proxy,target,method,args)) {
//反射原有对象方法
result=method.invoke(target, args);
}else {
interceptor.around(proxy,target,method,args);
}
//调用后置方法
interceptor.after(proxy,target,method,args);
return result;
}
}4.测试
package test1;
public class testMyInterceptor {
public static void main(String[] args) {
// TODO Auto-generated method stub
HelloWorld proxy=(HelloWorld)InterceptorJdkProxy.bind(new HelloWorldImpl(), "test1.MyInterceptor");
proxy.sayHelloWorld();
}
}反射方法前逻辑 取代了被代理对象的方法 反射方法后逻辑
拦截器可以进一步简化动态代理的使用方法。
来源:https://www.cnblogs.com/xc-xinxue/p/12371471.html