Dynamic proxy in proxy mode

Since JDK1.3, a dynamic proxy mechanism has been introduced into java. The related interfaces and classes are InvocationHandler and Proxy, which are located in the java.lang.reflect package.

The InvocationHandler interface defines only one abstract method:

        Object invoke(Object proxy, Method method, Object[] args) 

The two main static methods in the Proxy class:

        Class<?> getProxyClass(ClassLoader loader, Class<?>... interfaces) 

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

        getProxyClass returns a dynamically created proxy class (Class), and newProxyInstance returns an instance (Object) of the proxy class.

 

With the support of the JVM, proxy classes ("proxy roles") can be dynamically generated at runtime, and we can solve the problem of code bloat in the static proxy pattern.

After using a dynamic proxy, the "proxy role" will not be generated manually, but will be dynamically generated by the JVM at runtime by specifying three parameters: class loader, interface array, and call handler.

 

Here is an example of a dynamic proxy for the animal world:

 

Animal interface, has a running abstract method

/**
 * Created by jiangzhq on 2015/6/30.
 */
public interface Animal {
    void run();
}
  The implementation class of the animal interface - tiger
public class Tiger implements Animal {
    public void run() {
        System.out.println("The king of the forest - the tiger is running");
    }
}

 

Implementation class of animal interface - lion

public class Lion implements Animal{
    public void run() {
        System.out.println("The king of the grassland - the lion is running");
    }
}

 

Dynamic roles: dynamically generate proxy classes

public class DynamicProxy implements InvocationHandler {
    // The target object to be proxied
    private Object target;
    
    // inject via constructor
    DynamicProxy(Object obj) {
        this.target = obj;
    }

    // Dynamically generate objects through reflection
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        doBefore();
        Object result = method.invoke(target, args);
        doAfter ();

        return result;
    }

    public void doBefore(){
        System.out.println("Before dynamically generating proxy class");
    }

    public void doAfter(){
        System.out.println("After dynamically generating proxy class");
    }
    // Factory method to get the proxy class instance
    static <T> T factory(Object obj)
    {
        Class cls = obj.getClass();
        return (T)Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), new DynamicProxy(obj));
    }

}

 

Kind end test

public class DynamicProxyTest {

    public static void main(String[] args) {
        Animal tiger = new Tiger();
        Animal tigerProxy = (Animal) DynamicProxy.factory(tiger);
        tigerProxy.run();

        Animal lion = new Lion();
        Animal lionProxy = (Animal) DynamicProxy.factory(lion);
        lionProxy.run();
    }

}

 

Dynamic proxies are better oriented towards abstraction, reduce repetitive code, have better maintainability, and conform to the principles of interface-oriented programming.

Disadvantages: JDK's dynamic proxy can only proxy interfaces, not classes without interfaces.

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326338851&siteId=291194637