攔截器(由JDK動態代理實現的攔截器)
要實現攔截器,首先我們需要定義幾個類和接口
package com.xiawei.reflect.interceptor;
public interface JavaBenDao {
public void look();
}
==================================================
package com.xiawei.reflect.interceptor;
public class JavaBenDaoImpl implements JavaBenDao {
@Override
public void look() {
System.out.println("這是真實對象的方法!");
}
}
==================================================
這裏要自定義一個攔截器的接口,並且定義了三個抽象的方法
before(),around(),after()。這三個方法分別被用在執行反射
方法前;取代被代理的對象時;在執行反射方法後三個節點。
package com.xiawei.reflect.interceptor;
import java.lang.reflect.Method;
/**
* 自定義攔截器的接口
* @author Administrator
*
*/
public interface InterceptorDao {
public boolean before(Object proxy,Object target,Method method,Object[] args);
public void around(Object proxy,Object target,Method method,Object[] args);
public void after(Object proxy,Object target,Method method,Object[] args);
}
====================================================
package com.xiawei.reflect.interceptor;
import java.lang.reflect.Method;
/**
* 攔截器實現類
* @author Administrator
*
*/
public class InterceptorDaoImpl implements InterceptorDao{
@Override
public boolean before(Object proxy, Object target, Method method, Object[] args) {
System.out.println("在執行反射方法前執行的邏輯!");
return true;//默認值false表示不返回代理對象的原有方法
}
@Override
public void around(Object proxy, Object target, Method method, Object[] args) {
System.out.println("取代被代理的對象的方法!");
}
@Override
public void after(Object proxy, Object target, Method method, Object[] args) {
System.out.println("在執行反射方法後執行的邏輯!");
}
}
====================================================
這裏創建一個JDK動態代理類,再在動態代理中使用攔截器
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 在動態代理中使用攔截器</p>
* 動態代理類
* @author Administrator
*
*/
public class JdkInterceptorClass implements InvocationHandler {
/**
* 真實對象
*/
private Object target;
/**
* 攔截器的全限定名
*/
private String interceptorClass;
public JdkInterceptorClass(Object target, String interceptorClass) {
this.target = target;
this.interceptorClass = interceptorClass;
}
//綁定委托對象,並返回一個代理站位
public static Object bind(Object target,String interceptorClass){
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(), new JdkInterceptorClass(target,interceptorClass));
}
/**
* 通過代理對象調用方法,首先進入invoke()
* @param proxy 代理對象
* @param method 被調用的方法
* @param args 方法參數
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//判斷,如果攔截器全限定名為空,也就是沒有設置攔截器則反射原有方法(真實對象的方法)
if(interceptorClass == null){
return method.invoke(target, args);
}
//通過反射生成攔截器
Object result = null;//定義執行以下邏輯後的返回值
InterceptorDao interceptor =
(InterceptorDao) Class.forName(interceptorClass).newInstance();
//調用真實對象的方法前的方法邏輯
if(interceptor.before(proxy, target, method, args)){
//如果為true,則反射原有(真實)對象方法
result = method.invoke(target, args);
}else{
//如果為false,執行around()方法
interceptor.around(proxy, target, method, args);
}
//調用真實對象的方法後的方法邏輯
interceptor.after(proxy, target, method, args);
return result;
}
}
=========================================================
好了,代碼完成後我們測試一下,寫個測試類
package com.xiawei.reflect.interceptor;
public class Test {
public static void main(String[] args) {
//獲得代理對象
JavaBenDao proxy = (JavaBenDao) JdkInterceptorClass.bind(new JavaBenDaoImpl(),
"com.xiawei.reflect.interceptor.InterceptorDaoImpl");
//調用真實對象的方法
proxy.look();
}
運行結果:
在執行反射方法前執行的邏輯!
這是真實對象的方法!
在執行反射方法後執行的邏輯!
可以將上面的 before()方法的返回值改為false試一下.哈哈
攔截器(由JDK動態代理實現的攔截器)