天天看點

代理咋個寫,瞧這篇

導語

最近在看小傅哥的設計模式時,看到他的抽象工廠中使用了代理,正好這個代理還未接觸過,正好學習一下。

正文開始了

啥是代理呢?

對象的執行方法,交給代理來負責

本質還是調用對象的方法,類似于中介。

關鍵類/接口

  • InvocationHandler
InvocationHandler接口是proxy代理執行個體的調用處理程式實作的一個接口,每一個proxy代理執行個體都有一個關聯的調用處理程式;在代理執行個體調用方法時,方法調用被編碼分派到調用處理程式的invoke方法
/**
    * 該方法代理時執行某個方法會被自行調用
    * proxy:代理類代理的真實代理對象com.sun.proxy.$Proxy0
    * method:我們所要調用某個對象真實的方法的Method對象
    * args:指代代理對象方法傳遞的參數
    */
    public Object invoke(Object proxy, Method method, Object[] args)
        throws Throwable;
           
  • Proxy
Proxy類就是用來建立一個代理對象的類,它提供了很多方法,但是我們最常用的是newProxyInstance方法。

如何使用

  • 擷取一個代理
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

/**
 * @program: demo
 * @author: zzg
 * @create: 2020-09-29 14:42
 */


public class ProxyUtil {

    /**
     *
     * @Param interfaceClass 某個中介
     * @Param cacheAdapter 某個賣家
     * @author zzg
     * @date 2020/10/12
     * @return T
     * @throws
     */
    public static <T,G> T getProxy(Class<T> interfaceClass,G  cacheAdapter) throws Exception {

        // 擷取一個代理執行處理器
        InvocationHandler handler = new JDKInvocationHandler<G>(cacheAdapter);
        //目前線程所運作的類加載器,動态加載jar、資源檔案的時候使用
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        //獲得interfaceClass所實作的所有接口哦
        Class<?>[] classes = interfaceClass.getInterfaces();
        //建立一個代理對象
        return (T) Proxy.newProxyInstance(classLoader, new Class[]{classes[0]}, handler);
    }
}

           
  • 實作InvocationHandler
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

/**
 * @program: demo
 * @author: zzg
 * @create: 2020-09-30 15:17
 */

class JDKInvocationHandler<T> implements InvocationHandler {

    private T cacheAdapter;

    public JDKInvocationHandler(T cacheAdapter) {
        this.cacheAdapter = cacheAdapter;
    }

    /**
     * proxy:代理類代理的真實代理對象com.sun.proxy.$Proxy0
     * method:我們所要調用某個對象真實的方法的Method對象
     * args:指代代理對象方法傳遞的參數
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
       // 查找賣家的同名方法
        Method method1 = cacheAdapter.getClass().getMethod(method.getName(), ClassLoaderUtils.getClazzByArgs(args));
        //賣家執行
        return method1.invoke(cacheAdapter, args);
    }

}
           
  • 測試
    • 兩個類 加 測試方法
import com.example.demo.proxy.service.ProxyService;
import com.example.demo.service.TestService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @program: demo
 * @author: zzg
 * @create: 2020-09-30 15:59
 */
@Service("ProxyService")
public class ProxyServiceImpl implements ProxyService {

    @Autowired
    private TestService testService;

    @Override
    public void ceshi(String name, String age) {
        testService.getTaet();
        System.out.println("ProxyServiceImpl===="+name+"====="+age);
    }
}







import com.example.demo.proxy.service.ProxyService;
import com.example.demo.service.TestService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @program: demo
 * @author: zzg
 * @create: 2020-09-30 16:00
 */

@Service("PService")
public class PServiceImpl implements ProxyService {

    @Autowired
    private TestService testService;
    @Override
    public void ceshi(String name, String age) {
        testService.getTaet();
        System.out.println("PServiceImpl===="+name+"====="+age);
    }
}


   @Test
    void proxyTest() {
        try {
            ProxyService proxy = ProxyUtil.getProxy(ProxyServiceImpl.class,applicationContext.getBean("ProxyService"));
            proxy.ceshi("zzg1","10");
            ProxyService proxy1 = ProxyUtil.getProxy(ProxyServiceImpl.class, applicationContext.getBean("PService"));
            proxy1.ceshi("zzg","10");

        } catch (Exception e) {
            e.printStackTrace();
        }


    }
           
  • 結尾–廣告推廣
    代理咋個寫,瞧這篇