天天看點

java代理對象代理對象

代理對象

代理

是一種設計模式,他提供了對目标對象的一種通路方式(通過代理對象去通路目标對象)

使用的程式設計思想

不要随意去修改别人已經寫好的代碼或者方法,如果需改修改,可以通過代理的方式來擴充該方法

最基本的例子

如果你要邀請一個明星來參加活動,你要聯系明星的經紀人而不是聯系明星本人來達到同樣的目的,明星是咱們的目标對象,他是要來參加活動中的節目,剩下的其他事情都是他的經紀人來處理

代理模式的關鍵點是

代理對象與目标對象.代理對象是對目标對象的擴充,并會調用目标對象

靜态代理

靜态代理在使用時,需要定義接口或者父類,目标對象與代理對象一起實作相同的接口或者是繼承相同父類.

好處:

在目标對象的基礎上增加額外的功能操作。

缺點:

因為代理對象需要與目标對象實作一樣的接口,是以會有很多代理類,類太多.同時,一旦接口增加方法,目标對象與代理對象都要維護.

public interface IUserDao {
    public void save();
}
           
/**
 *
 * 接口實作
 * 目标對象
 *
 */
public class UserDao implements IUserDao {

    @Override
    public void save() {
        System.out.println("明星參加活動做節目");
    }
}

           
/**
 *
 * 實作接口
 * 代理對象,靜态代理
 *
 */
public class UserDaoProxy  implements  IUserDao{

    private IUserDao target;

    public UserDaoProxy(IUserDao target) {
        this.target = target;
    }

    @Override
    public void save() {
        System.out.println("活動之前經紀人處理瑣碎的事情");
        target.save();
        System.out.println("活動之後經紀人處理瑣碎的事情");
    }
}

           
public class ProxyTest {
    public static void main(String[] args) {
        //目标對象
        UserDao target = new UserDao();

        //代理對象
        UserDaoProxy userDaoProxy = new UserDaoProxy(target);

        //執行的是代理的方法
        userDaoProxy.save();

    }
}

           

運作結果

java代理對象代理對象

動态代理

特點:

  1. 代理對象,不需要實作接口
  2. 代理對象的生成,是利用JDK的API,動态的在記憶體中建構代理對象(需要我們指定建立代理對象/目标對象實作的接口的類型)
  3. 動态代理也叫做:JDK代理,接口代理

JDK中生成代理對象的API

代理類所在包:java.lang.reflect.Proxy

JDK實作代理隻需要使用newProxyInstance方法,但是該方法需要接收三個參數,完整的寫法是:

static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h )
/*
注意該方法是在Proxy類中是靜态方法,且接收的三個參數依次為:

ClassLoader loader,:指定目前目标對象使用類加載器,擷取加載器的方法是固定的
Class<?>[] interfaces,:目标對象實作的接口的類型,使用泛型方式确認類型
InvocationHandler h:事件處理,執行目标對象的方法時,會觸發事件處理器的方法,會把目前執行目标對象的方法作為參數傳入
*/
           

注意

代理對象不需要實作接口,但是目标對象一定要實作接口,否則不能用動态代理

public interface IUserDao {
    public void save();
}

           
/**
 *
 * 接口實作
 * 目标對象
 *
 */
public class UserDao implements IUserDao {

    @Override
    public void save() {
        System.out.println("明星參加活動做節目");
    }
}

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

public class ProxyFactory {
    //維護一個目标對象
    private Object target;
    public ProxyFactory(Object target){
        this.target=target;
    }

    //給目标對象生成代理對象
    public Object getProxyInstance(){
        return Proxy.newProxyInstance(
                target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        System.out.println("活動之前經紀人處理瑣碎的事情");
                        //執行目标對象方法
                        Object returnValue = method.invoke(target, args);
                        System.out.println("活動結束後經紀人處理瑣碎的事情");
                        return returnValue;
                    }
                }
        );
    }
}
           
public class DHCPProxyTest {
public static void main(String[] args) {
        // 目标對象7
        IUserDao target = new UserDao();
        //原始的類型 class com.rsw.DHCPproxy.dao.UserDaoo
        System.out.println(target.getClass());
        // 給目标對象,建立代理對象
        IUserDao proxy = (IUserDao) new ProxyFactory(target).getProxyInstance();
        // class com.sun.proxy.$Proxy0   記憶體中動态生成的代理對象
        System.out.println(proxy.getClass());
        // 執行方法執行的是代理對象的方法!
        proxy.save();
        }

}

           

運作結果

java代理對象代理對象

代碼打包