Examples and implementation of static agent and dynamic agent

Posted by damienmcd on Mon, 20 Dec 2021 03:25:44 +0100

preface

   proxy mode. We will explain it here in combination with JAVA static proxy and dynamic proxy. It is similar to Spring AOP aspect oriented programming: enhanced message is also a proxy mode.

   what are the differences between our static proxy and dynamic proxy and (service) interface and (serviceImpl) interface implementation classes? The concept of static proxy is similar to its understanding. It can be said that static proxy is an enhanced message of implementation classes. Moreover, static proxy is aimed at the implementation classes of all implementation interfaces (implemented through upward transformation).

Static proxy

Implementation Brief

   it is essentially an interface and a proxy, which performs "enhanced" (additional) operations on all implementation classes of the interface:

   the following example: the human interface has two implementation classes: man and woman. We need to say that each human interface is created by god (enhanced operation) when it is implemented. Then we manually implement a GodProxy static proxy class for the human interface. Then we can introduce enhanced operation when we execute the methods of the implementation object of the human interface through this proxy.

Create human interface

public interface Human {
    public void sex();
}

Create interface implementation class

public class Man implements Human{
    @Override
    public void sex() {
        System.out.println( "this is Man" );
    }
}

public class Women implements Human{
    @Override
    public void sex() {
        System.out.println( "this is Women" );
    }
}

Create a proxy that implements enhanced operations on the interface

public class GodProxy implements Human{

    Human huamnGenarator;

    public GodProxy(Human huamnGenarator){
        this.huamnGenarator = huamnGenarator;
    }

    @Override
    public void sex() {
        System.out.println( "God begin to make human" );
        huamnGenarator.sex();
        System.out.println(" End of work ");
    }
}

Agent implementation effect

public class Static proxy {
    public static void main(String[] args) {
        GodProxy proxy_1 = new GodProxy(new Man());
        GodProxy proxy_2 = new GodProxy(new Women());

        proxy_1.sex();
        System.out.println("\n\n");
        proxy_2.sex();
    }
}

[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-GJFzti0a-1629609568788)(D: \ blog drawing \ blog backup \ images \ agent \ image-20210820204632913.png)]

Dynamic agent

Implementation Brief

   compared with static proxy, a proxy class proxy can only implement operations on one interface. As we all know, classes can implement multiple interfaces. Can we implement enhanced operations on the interfaces of all implementation classes? Yes, we need to make the incoming parameter Object through reflection and upward transformation, but the getClass method in Object obtains the class Object, In fact, it is the class that implements the class (known from the upward transformation feature of Java). Get the class Object that implements the class Object and the interface array it implements. We can achieve this goal: This is dynamic proxy: implement static proxy for multiple interfaces.

  the dynamic proxy class mainly implements the InvocationHandler interface, which implements the invoke method to implement enhanced operations. A user-defined method is used to create and bind dynamic proxy classes and input parameters (transformed upward into obj implementation class objects), so as to realize the enhanced operation of implementation class object methods.

Here we have two questions:

  1. How to implement the enhanced invoke method—— Through Java lang.reflect. Proxy. In the newproxyinstance method, restore the obj object transformed upward to the original object (the specific implementation class object), and bind the enhanced invoke method.

  2. How proxy objects reproduce object methods—— Take advantage of the recovery invariance of upward transformation.

Key point: upward transformation

Upward Transformation: the subclass instance is assigned to the parent class reference. The subclass extension method cannot be called, but her implementation does exist:

        Object obj = new Girl();
        Girl girl = (Girl) obj;
        System.err.println(obj.getClass().getName());
        System.err.println(obj.getClass().getInterfaces().length);
        girl.nickName();

Output:

src. Agent mode Girl
2

girl

Create YoungMan interface

The Human interface, two interfaces, will also be used here.

public interface YoungMan {
    public void nickName();
}

Create two interface implementation classes

public class Boy implements Human,YoungMan{
    @Override
    public void sex() {
        System.out.println( "this is Man" );
    }

    @Override
    public void nickName() {
        System.out.println( "juvenile" );
    }
}


public class Girl implements Human,YoungMan{
    @Override
    public void sex() {
        System.out.println( "this is Women" );
    }

    @Override
    public void nickName() {
        System.out.println( "girl" );
    }
}

Create a dynamic proxy instance object

Here we mainly use proxy The newproxyinstance method creates a proxy class and passes the following parameters:

   public static Object newProxyInstance(ClassLoader loader, 
                                            Class<?>[] interfaces, 
                                            InvocationHandler h)

  • Class loader: specifies which classloader the proxy class is loaded by;
  • The proxy class needs the interface method implemented by the proxy;
  • InvocationHandler object: indicates which InvocationHandler object will be associated with when the dynamic proxy object calls the method, and finally called by it to implement the enhanced method (i.e. invoke method).

Note that the returned custom newProxyInstance here is Object.

args in the invoke method are the parameters passed in by the method;

public class GodForYoungProxy implements InvocationHandler {

    private Object godForYoungProxy;

    //Parameter to design an upward transformation for Object
    public Object newProxyInstance(Object godForYoungProxy) {
        this.godForYoungProxy = godForYoungProxy;
        //this refers to the InvocationHandler implementation class GodForYoungProxy
        System.err.println( godForYoungProxy.getClass().getName() );
        return Proxy.newProxyInstance(godForYoungProxy.getClass().getClassLoader(), godForYoungProxy.getClass().getInterfaces(), this);
    }


    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println(" God for Young begin to work ... ");
        proxy = method.invoke(godForYoungProxy, args);
        System.out.println(" End of work ");
        return proxy;
    }
}


Agent implementation effect

public class Dynamic agent {
    public static void main(String[] args) {
        GodForYoungProxy godForYoungProxy = new GodForYoungProxy();
        Human human = (Human) godForYoungProxy.newProxyInstance(new Boy());
        YoungMan youngMan = (YoungMan) godForYoungProxy.newProxyInstance(new Boy());

        human.sex();
        youngMan.nickName();

        //Upward transformation test
//        Object obj = new Girl();
//        Girl girl = (Girl) obj;
//        System.err.println(obj.getClass().getName());
//        System.err.println(obj.getClass().getInterfaces().length);
//        girl.nickName();
    }
}

The obj in the proxy generation object is transformed upward getClass().getName() print:

Topics: Java Big Data Design Pattern Dynamic Proxy