jdk dynamic agent

Posted by Round on Sun, 12 Dec 2021 12:44:44 +0100

catalogue

1 Preface

2. Agency mode

2.1 static agent

         2.1. 1 static proxy implementation

2.2 dynamic agent

         2.2. 1 several ways of dynamic agent implementation

         2.2. 2. Implement dynamic agent

1 Preface

Proxy mode: it refers to providing a proxy for other objects to control access to this object. In some cases, an object is not suitable or can not directly reference another object, and the proxy object can play an intermediary role between the customer class and the target object.

The proxy object is used to enhance the main business logic without modifying the target object. The object that the customer class really wants to access is the target object, but what the customer can access is the proxy object. The customer class accesses the target object by accessing the proxy class.

effect:

1 function enhancement: you have added additional functions to your original functions. The newly added functions are called function enhancement

2 control access: the proxy class does not allow you to access the target

2. Agency mode

2.1 static agent

1) The proxy class is implemented manually

2) The objects you need to proxy are determined

         2.1. 1 static proxy implementation

Step 1: define an interface for selling u disks

Step 2: create a manufacturer's class to implement the method of selling u disks in step 1

Step 3: create a merchant (agent) and implement the interface in step 1

Step 4: create a client class and call the merchant method to buy u disk

Code implementation:

Step 1: define an interface for selling u disks

public interface UsbSell {

    /**
     * Define a method that manufacturers and businesses should use to complete the function
     * @param amount Quantity purchased
     * @return
     */
    float sell(int amount);
}

Step 2: create a manufacturer's class to implement the method of selling u disks in step 1

//Target manufacturers only supply to middlemen and do not want to supply to individual small businesses
public class UsbFactory implements UsbSell {
    @Override
    public float sell(int amount) {
        //The price of a U SB flash disk is 65 yuan
        float price = 65.0f;
        return amount*price;
    }
}

Step 3: create a merchant (agent) and implement the interface in step 1

//Agent - middleman
public class TaoBao implements UsbSell {

    //The agent is the target manufacturer class defined by Kingston
    private UsbFactory usbFactory =  new UsbFactory();

    @Override
    public float sell(int amount) {
        //Call target method
        float price = usbFactory.sell(amount);

        price =  (price + 15)*amount;
        return price;
    }
}

Step 4: create a client class and call the merchant method to buy u disk

    @Test
    public void test7(){
        TaoBao taoBao = new TaoBao();
        float sell = taoBao.sell(80);
        System.out.println("***Total amount****"+sell); //***Total amount * * * * 417200.0
    }

It can be seen that when we buy u-disk through agent middlemen, each u-disk by middlemen earned a price difference of 15 yuan.

We can find that the function of price increase is performed after calling the target class. In fact, this step is equivalent to an enhancement of our function (the proxy class will be enhanced when completing the function). At the same time, we can also perform some other function enhancements, such as returning coupons or red envelopes, Any function performed after the completion of our original functions belongs to function enhancement.

Advantages and disadvantages of static agent:

Advantages: easy to realize, simple and easy to understand

Disadvantages: when the target class increases, the agent will increase. The interface function has been modified, and the merchant and agent classes have been changed

2.2 dynamic agent

Dynamic proxy: in the process of program execution, use the reflection mechanism of jdk to create proxy class objects and dynamically specify the target class to proxy. (dynamic proxy is the ability to create Java objects, which eliminates the need to create proxy class objects ourselves.)

2.2. 1 several ways of dynamic agent implementation

1 cglib dynamic proxy: cglib is a third-party tool library to create proxy objects. The principle of cglib is inheritance. Cglib creates its subclass by inheriting the target class, and rewrites the method of duplicate name in the parent class in the subclass to modify the function

Because cglib inherits and rewrites methods, the classes to be inherited and the rewritten methods cannot be final. Cglib is used in the frameworks of mybatis and spring

2 dynamic Proxy of JDK: use the classes and interfaces in java reflection package to realize the function of dynamic Proxy. Reflection package: Java lang reflect three classes: InvocationHandler, Method and Proxy

1) InvocationHandler interface (calling processor): a method invoke() Represents the function code to be executed by the proxy object. The functions to be completed by the proxy class function are written in the invoke () method.

Functions completed by proxy class:

Call the target method to perform the function of the target method

Function enhancement: when the target method is called, the function is enhanced

Method prototype:

Parameters:

Object proxy: the proxy object created by jdk without assignment

Method: the method in the target class. The jdk provides the method object

Object[] args: parameter of method in target class

public Object invoke(Object proxy, Method method, Object[] args)
    throws Throwable;

2) Method: represents the of the method (the method in the target class)

Function: Method can be used to execute the Method of a target class Invoke (target object, target parameter);

Note: the invoke method here is not the same as the invoke method in the InvocationHandler class

3)Proxy class: to create a proxy object, instead of creating the object through the previous construction method of new class, the method in proxy class is used instead of new

method; Static method newProxyInstance()

Parameters:

ClassLoader class loader: the loader responsible for loading objects into memory. Use reflection to get the ClassLoader of the object (for example, class B > > b.getcalss(). Getclassloader()) and the ClassLoader of the target object

Class<?> Interface: the interface implemented by the target object, which is also obtained through reflection

InvocationHandler h: the function to be completed by the proxy class

public static Object newProxyInstance(ClassLoader loader,

Class<?> interface,InvocationHandler h)

2.2. 2. Implement dynamic agent

Step 1: create an interface and define the functions to be completed by the target class

public interface UsbSell {

    float sell(int amount);
}

Step 2: create a target class to implement the interface

public class UsbSellFactory implements UsbSell{

    @Override
    public float sell(int amount) {
        System.out.println("Enter the method executed in the target class");
        return 65.0f*amount;
    }
}

Step 3: create the implementation class of InvocationHandler interface and complete the function of the agent in the invoke method (1 call the target method 2 enhance the function)

public class SellHandle implements InvocationHandler {

    /**
     * Define a target to represent the proxy object to be passed in
     */
    private Object taeget = null;

    public SellHandle(Object taeget) {
        //Target object
        this.taeget = taeget;
    }

    /**
     * Call processor
     * 1 Call target method 2 enhancements
     * @param proxy
     * @param method
     * @param args
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {


        /**
         * 1 Executing the target method jdk will automatically substitute the parameter args into
         */
        Object invoke = method.invoke(taeget, args);

        /**
         * 2 Enhance the function and sell each USB flash disk with a price increase of 25 yuan
         */
        if (invoke != null ){
           Float price =  (Float)invoke;
           int num =  Integer.parseInt(args[0].toString());
           price = (price + 25.0f)*num;
           invoke = price;
        }


        return invoke;
    }
}

Step 4: use the static method of Proxy class to create Proxy object and convert the return value to interface type

public class MainShop {

    public static void main(String[] args) {

        //1 create target object
        UsbSell factory = new UsbSellFactory();

        //2 create InvocationHandler object
        InvocationHandler handle = new SellHandle(factory);

        //3 Create proxy object
        UsbSell proxy = (UsbSell)Proxy.newProxyInstance(
                factory.getClass().getClassLoader(),
                factory.getClass().getInterfaces(),
                handle);

        //4 execution method through agent
        float sell = proxy.sell(10);
        System.out.println("Through dynamic proxy,Call method:"+sell);

    }
}

Execution results:

Summary: the jdk dynamic proxy creates the proxy object execution method. In fact, it calls the target method in the InvocationHandler class. After calling the target method, it performs a function enhancement, and then returns a result.