jdk動態代理,代理模式的一種,只能代理接口。
必要條件就是 代理類必須實現InvocationHandler 接口,被代理的類必須是實現接口的類。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 動態代理類,jdk動態代理的核心。
* 代理類必須實現InvocationHandler並實現invoke方法,"增強"的位置就在這裏
*/
public class Dtdl implements InvocationHandler {
private Object insta;
public Dtdl(Object insta1) {
insta = insta1;
}
/**
* 獲取代理對象的接口
* 方法返回值使用泛型,這樣調用的地方就可以不用強轉了。
* @param <T>
* @return
*/
public <T> T getProxy(){
return (T) Proxy.newProxyInstance(insta.getClass().getClassLoader(),insta.getClass().getInterfaces(),this);
}
/**
*
* @param proxy 這個參數可以使用反射獲取代理類的對象信息,可以將代理對象返回進行連續調用。基本用不上
* @param method 被代理的方法
* @param args 被代理的類的參數
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("前置增強"+args[0]);
args[0]= (Integer)args[0]+2 ;
Object o = method.invoke(insta,args);
System.out.println("後置增強");
return o;
}
}
/**
* 動態代理是基於接口實現的,目標類必須實現了接口,並且必須是接口中的方法
*/
interface MovenInt {
int mytest(int b);
}
/**
* 被代理的類既實現了父接口的一個子類
*/
class Moven implements MovenInt{
/**
* 能被代理類執行的方法是實現於接口的,
* 接口中沒有的話調用不到
* @param b
* @return
*/
public int mytest(int b){
System.out.println(b);
return 0;
}
}
/**
* 測試類,裏邊就一個main方法,裏邊描述了動態代理的調用的方式
*/
class TestMy{
/**
*
* @param args
*/
public static void main(String[] args) {
//用動態代理類提供的方法獲取到被代理類實現的接口。
MovenInt d = new Dtdl(new Moven()).getProxy();
int i = d.mytest(5);
System.out.println("結束"+ i);
}
}