Java is really not difficult (thirty-four) proxy mode (2)

Proxy Mode (2): Dynamic Proxy

1. Dynamic proxy mode

Features of dynamic proxy:

  1. When proxying an object, you don't need to implement an interface
  2. The generation of the proxy object is to use the JDK API to dynamically build the proxy object in memory (requires us to specify the type of the interface implemented by the proxy object/target object)

Another name for dynamic proxy: JDK proxy, interface proxy


2. JDK dynamic proxy

Class Diagram:
insert image description here

The Java dynamic proxy class is located under the java.lang.reflect package

Generally, it mainly involves the following two categories:

1. Interface InvocationHandler: Only one method
public object invoke(Object obj, Method method, Object[] args) is defined in this interface. In actual use, the first parameter obj generally refers to the proxy class, and method is the proxy method , args is the parameter array of the method. This abstract method is implemented dynamically in the proxy class.

2. Proxy: This class is the dynamic proxy class

static Object newProxyInstance(ClassLoader loader, Class[] interfaces,InvocationHandler h):

Returns an instance of the proxy class, and the returned proxy class can be used as the proxy class (the method declared in the interface of the proxy class can be used)

The implementation steps of dynamic generation:

  1. Create a class that implements the interface InvocationHandler, it must implement the invoke method
  2. Create proxied classes and interfaces
  3. Call the static method of Proxy to create a proxy class: newProxyInstance(ClassLoader loader,Class[]
  4. Invoke a method through a proxy

3. JDK dynamic proxy code demonstration

For example, there is now a method for driving a car:

public interface Moveable {
    
    
    void move();
}

There is now a car:

//实现Moveable 接口,并随机暂停一段时间

import java.util.Random;
public class Car implements Moveable{
    
    
    @Override
    public void move() {
    
    
        try{
    
    
            Thread.sleep(new Random().nextInt(1000));
            System.out.println("汽车行驶中");
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
    }
}

Time agent class:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class TimeHandler implements InvocationHandler{
    
    

    public TimeHandler(Object target){
    
    
        super();
        this.target = target;
    }
    private Object target;


    /**
     *
     * @param proxy :被代理的对象
     * @param method:被代理对象的方法
     * @param args:方法的参数
     * @return
     * @throws Throwable
     * 返回值:Object 方法的返回值
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
    
        long startTime = System.currentTimeMillis();
        System.out.println("汽车开始行使");

        method.invoke(target);

        long endTime = System.currentTimeMillis();
        System.out.println("汽车行驶结束,行驶的时间为:"+(endTime-startTime)+"毫秒");
        return null;
    }
}

Test class:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

public class Test {
    
    
    public static void main(String[] args) {
    
    

        Car car = new Car();
        InvocationHandler h = new TimeHandler(car);
        Class<?> cls = car.getClass();

        /**
         * newProxyInstanced的参数
         * 分别是:类加载器、实现的接口、实现的处理器
         */
        Moveable m = (Moveable) Proxy.newProxyInstance(cls.getClassLoader(),
                cls.getInterfaces(),h);
        m.move();
    }
}

The output of this is:

汽车开始行使
汽车行驶中
汽车行驶结束,行驶的时间为:137毫秒
//后面的时间是随机产生的,每次都不一样

Notice:

  • JDK proxy can only proxy the class that implements the interface, and can not proxy the class that does not implement the interface

insert image description here


The above is the JDK dynamic proxy, and of course the cglib dynamic proxy :

cglib implements proxy for classes. The principle of cglib is to generate a subclass for the specified target class and overwrite the method to achieve enhancement. However, because inheritance is used, it cannot proxy the final modified class, because the small application The seniors themselves have not fully grasped this part, so I will not explain more here. You can refer to the technical articles of other bloggers.

Perfect end to March! Finally, Senior Xiaoying is very grateful to everyone for their support and companionship. Your support is my biggest motivation, and I will continue to write articles that everyone likes!

insert image description here

Guess you like

Origin blog.csdn.net/m0_57310550/article/details/123810327