1. 程式人生 > >java反射機制應用之動態代理

java反射機制應用之動態代理

代理類 過多 size bject interface 並且 編譯期 代理 抽象

1.靜態代理類和動態代理類區別

靜態代理:要求被代理類和代理類同時實現相應的一套接口;通過代理類的對象調用重寫接口的方法時,實際上執行的是被代理類的同樣的

方法的調用。

動態代理在程序運行時,根據被代理類及其實現的接口,動態的創建一個代理類。當調用代理類的實現的抽象方法時,就發起對被代理類同樣方法的調用。

涉及到的技術點:

①提供一個實現了InvocationHandler接口實現類,並重寫其invoke()方法

②Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),h);

2.動態代理的優點

它可以在程序運行時動態的為任何想要被代理的類生成代理對象(代理對象中包含了編寫的通用代理邏輯),它不用去關心被代理的類到底是怎樣的,可以與被代理的類完全脫離關系,從而靈活的運用到不同的應用場景中。

下面通過具體的代碼來體現動態代理的好處

第一個是靜態代理的代碼

package 反射機制;
//靜態代理特征是代理類和目標對象的類都是在編譯期間確定下來的
//不利於程序的擴展。同時,每一個代理類只能為一個接口服務,這樣一來
//程序開發必然產生過多的代理
//接口
interface ClothProduct{
void productCloth();
}

//被代理類
class NikeClothFactory implements ClothProduct{

@Override
public void productCloth() {
System.out.println("nike生產一批衣服");

}

}
//代理類
class ProxyFactory implements ClothProduct{
ClothProduct cf;
//創建代理類的對象時,實際傳入一個被代理類的對象
public ProxyFactory(ClothProduct cf) {
this.cf=cf;
}
@Override
public void productCloth() {

System.out.println("代理類開始執行");
cf.productCloth();
}

}
public class JingTaiDaiLi {
public static void main(String[] args) {
NikeClothFactory nc=new NikeClothFactory();
ProxyFactory proxy=new ProxyFactory(nc);
proxy.productCloth();
}
}
//每建立一個被代理類就必須建立一個代理類,則多個被代理類就得寫多個代理類太麻煩

下面是動態代理類

package 反射機制;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

//動態代理是指客戶通過代理類來調用其他對象的方法,
//並且是在程序運行時根據需要動態創建目標類的代理對象

interface Subject{
void action();
}

//被代理類
class RealSubject implements Subject{
public void action()
{
System.out.println("我是被代理類");
}
}

class MyIvocationHandler implements InvocationHandler{
Object obj;//實現了接口的被代理類的對象的聲明
//給被代理類的對象實例化,返回一個代理類的對象
public Object blind(Object obj) {
this.obj=obj;

return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this) ;
}
//當通過代理類的對象發起對重寫的方法調用時都會轉化為對如下的Invoke方法的調用
@Override
public Object invoke(Object arg0, Method arg1, Object[] arg2) throws Throwable {
Object obj1=arg1.invoke(obj, arg2);

return obj1;
}
}
public class DongTaiDaiLi {
public static void main(String[] args) {
//被代理類的對象
RealSubject rs=new RealSubject();
//2創建一個實現實現IvocationHandler接口的類的對象
MyIvocationHandler mh=new MyIvocationHandler();
//3調用blind()方法,動態的返回一個同樣實現real所在類的接口subject的代理類的對象
Object obj=mh.blind(rs);
Subject sub=(Subject)obj;//此時sub就是代理類對象
sub.action();//轉到IvocationHandler接口的實現類的invoke()方法的調用
System.out.println();
//利用靜態代理的被代理類體現動態代理
NikeClothFactory Nick=new NikeClothFactory();
//ClothProduct cp=new ClothProduct();
ClothProduct cp=(ClothProduct)mh.blind(Nick);
cp.productCloth();
}
}

所有被代理類都對應一個代理類,當通過代理類的對象發起對重寫的方法調用時都會轉化為對唯一一個代理類的Invoke方法的調用,不同的被代理類對應不同的method,所以invoke方法是動態變化的,,方便對多個被代理類的代理。。

java反射機制應用之動態代理