Agent model of design pattern

Agent model of design pattern

Definition of proxy mode: proxy mode provides a proxy object for an object, and the proxy object controls the reference to the original object. This type of design pattern belongs to structural pattern.
For example, if a restaurant wants to launch the takeout function, the first way is for customers to call the restaurant and order. However, few people may know that the restaurant has launched the takeout function. The second is to launch the takeout function on meituan. Meituan helps the restaurant to pick up the order.

There are two kinds of agents: static agent and dynamic agent;
Before the static agent program runs, the agent class has been written in advance.
Dynamic agent is to dynamically create agent classes when the program is running. It is also divided into JDK dynamic agent and CGLIB dynamic agent. JDK dynamic agent is based on interface. The proxy class must implement an interface. Classes without interface can use CGLIB dynamic agent.

Static proxy

The code example is as follows:

Order.java

public interface Order {
    void order();
}
MeiTuan.java
```java
public class MeiTuan implements Order {

    private Restaurant restaurantA  = new Restaurant();

    public void order() {
        System.out.println("Received a sum A Takeout orders for restaurants");
        restaurantA.order();
    }
}

Restaurant.java

public class Restaurant implements Order {
    public void order() {
        System.out.println("A Restaurant, received an order from meituan");
    }
}

Main.java

public class Main {
    public static void main(String[] args) {
        //Open meituan client
        Order order = new MeiTuan();
        //place an order
        order.order();
    }
}

JDK dynamic agent

Interface Order.Java

public interface Order {
    void order();
}

Restaurant.java

public class Restaurant implements Order {
    public void order() {
        System.out.println("A Restaurant, received an order from meituan");
    }
}

Main.java

public class Main {
    public static void main(String[] args)  {
        Restaurant restaurant = new Restaurant();
        Order proxyMeietuan = (Order) Proxy.newProxyInstance(Order.class.getClassLoader(), new
                                Class[]{Order.class}, new MeituanProxy(restaurant));
        proxyMeietuan.order();
    }
}

Proxy.java

public class Proxy implements InvocationHandler {

    private Restaurant restaurant;

    public Proxy (Restaurant restaurant) {
        this.restaurant = restaurant;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("before order");
        method.invoke(restaurant,args);
        System.out.println("after order");
        return null;
    }
}

How to view classes generated by dynamic proxies
Use txt to replace the quotation marks with your own Java_ The path corresponding to home. After modification, change the file suffix to. bat

java -classpath "D:\Java\jdk1.8.0_261\lib\sa-jdi.jar" sun.jvm.hotspot.HSDB

Then open the. bat file and click attach to hotSpot process

Then enter the process number. If you don't know the process number, you can enter jps to query

Enter the process number and click class browser

Find proxy,
Click again


Then you can see that the desktop generates a folder with a class file in it

Pull the file into the idea and you can see the generated dynamic proxy class

public final class $Proxy0 extends Proxy implements Order {
    private static Method m1;
    private static Method m3;
    private static Method m2;
    private static Method m0;

    public final void order() {
        try {
            super.h.invoke(this, m3, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public $Proxy0(InvocationHandler var1) {
        super(var1);
    }

    static {
        try {
            m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
            m3 = Class.forName("com.design.proxy.Order").getMethod("order");
            m2 = Class.forName("java.lang.Object").getMethod("toString");
            m0 = Class.forName("java.lang.Object").getMethod("hashCode");
        } catch (NoSuchMethodException var2) {
            throw new NoSuchMethodError(var2.getMessage());
        } catch (ClassNotFoundException var3) {
            throw new NoClassDefFoundError(var3.getMessage());
        }
    }

    public final boolean equals(Object var1) {
        try {
            return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    public final String toString() {
        try {
            return (String)super.h.invoke(this, m2, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final int hashCode() {
        try {
            return (Integer)super.h.invoke(this, m0, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }
}

You can see that the generated proxy class inherits from proxy. Since java inherits from proxy, jdk dynamic proxy can only be used on the interface

Tags: Design Pattern

Posted on Thu, 02 Sep 2021 03:04:55 -0400 by Zoran_Dimov