代理模式 - 動態代理

读书声起五更天發表於2024-09-23

動態代理的API

Proxy 動態代理類

  • 生成代理物件:Proxy.newProxyInstance( 類載入器介面陣列處理器 )
    • 類載入器:物件.getClass( ).getClassLoader( )
    • 介面陣列-被代理類的所有介面:被代理物件.getClass( ).getInterfaces( )
    • 處理器:代理物件呼叫方法時,會被處理器攔截

InvocationHandler 處理器介面

  • 處理器的作用:攔截方法的執行
  • 代理物件呼叫方法時,必須經過處理器的invoke( )方法

動態代理的角色分析


動態代理的模板程式碼


// 動態代理公式
// T t=(T)Proxy.newProxyInstance(類載入器,介面陣列,處理器);


T t=(T)Proxy.newProxyInstance(
                被代理物件.getClass().getClassLoader(),
                被代理物件.getClass().getInterfaces();
                (Object obj, Method method, Object[] args)->{
                      //方法執行前
                      
                      Object result = method.invoke(代理物件,args);
                      
                      //方法執行後
      
                      return result;
                 }
);
t.介面的方法() ;

應用例項

呼叫List集合remove( )時,刪除指定的元素(包含重複的元素)

public static void main(String[] args1) {
    //需求:呼叫List集合remove()時,刪除指定的元素,包含多個重複的元素
    //1.建立被代理物件
    List list = new ArrayList();
    Collections.addAll(list, 2, 3, 5, 2, 7, 2, 9,5, 6);
    System.out.println("呼叫方法前:"+list);

    //2.透過Proxy類 建立代理物件
    List listProxy=(List) Proxy.newProxyInstance(
            list.getClass().getClassLoader(),
            list.getClass().getInterfaces(),
            (Object obj, Method method, Object[] args)->{
                Object invoke = null;//目標方法的返回值,如果沒有,則不需要寫
                if("remove".equals(method.getName())){
                    //呼叫remove方法時,刪除所有指定的重複元素
                    while(true){
                        if (!list.contains(args[0])) {
                            break;
                        }
                        list.remove(args[0]);
                    }
                }else{
                    //其它方法,正常執行
                    invoke = method.invoke(list, args);
                }

                return invoke;

            }
    );
    //3.代理物件呼叫方法
    listProxy.remove(2);
    System.out.println("呼叫方法後:"+list);
}

相關文章