Java implements dynamic proxy

  • 2020-04-01 03:43:00
  • OfStack

The Java dynamic proxy class is located under the java.lang. Reflect package and generally involves the following two classes:
(1) InvocationHandler: only one method is defined in this interface
              Public object invoke(object obj,Method Method, object [] args)
              In practice, the first parameter obj generally refers to the proxy class, method is the method to be proxy, as in the example above, request(), args is the parameter array of the method. This abstract method is implemented dynamically in the proxy class.

(2) Proxy: this class is a dynamic Proxy class, similar to the ProxySubject in the above example, which mainly contains the following protected Proxy(InvocationHandler h) : constructor, used to assign the value of internal h.
              Static Class getProxyClass (ClassLoader loader, Class[] interfaces)
              Gets a proxy class where the loader is the class loader and the interfaces are an array of all the interfaces that the real class has.

              Static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)
              Returns an instance of the proxy class, which can be treated as a proxy-ridden class.     Use (methods declared in the Subject interface of the proxied class can be used)
   
              The Dynamic Proxy is a class that is generated at run time, and when it is generated you must         You give it a set of interfaces, and then the class declares that it implements those interfaces. Of course you can       An instance of this class is used as one of these interfaces. Of course, this Dynamic Proxy is actually & somalia;   It's an     Proxy, which doesn't do the actual work for you, you have to provide a handler when you generate an instance of it, and it       Take over the actual work.

When using the dynamic proxy class, we must implement the InvocationHandler interface:
      See the program subject.java
      See the program realsubject.java
      See program dynamicsubject.java
      See the program client.java


package com.langsin.dynamicproxy;
//Abstract role (previously abstract class, interface) :
public interface Subject
{
    abstract public void request();
}


package com.langsin.dynamicproxy;
//Specific role
public class RealSubject implements Subject
{
    public RealSubject()
    {
    
    }
    public void request()
    {
        System.out.println("From real subject.");
    }
}


package com.langsin.dynamicproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
//Agent processor
/**
 * The internal property of the proxy class is Object Class that is actually used by the constructor of that class DynamicSubject(Object obj) Assign a value to it;
 * In addition, it is implemented in this class invoke Method in the method method.invoke(sub,args);
 * This is simply calling the method that will be executed on the proxied object, the method parameter sub Is the actual proxied object,
 * args The parameters required to perform the corresponding operation on the proxied object.
 * With the dynamic proxy class, we can perform some operations before or after the invocation
 */
public class DynamicSubject implements InvocationHandler
{
    private Object sub;
    public DynamicSubject()
    {
    }
    public DynamicSubject(Object obj)
    {
        sub = obj;
    }
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
    {
        System.out.println("before calling " + method);
        method.invoke(sub, args);
        System.out.println("after calling " + method);
        return null;
    }
}


package com.langsin.dynamicproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
//Client
public class Client
{
    static public void main(String[] args) throws Throwable
    {
        RealSubject rs = new RealSubject(); //Here you specify the proxied class
        InvocationHandler ds = new DynamicSubject(rs);
        Class<?> cls = rs.getClass();
        
        //The following is a one-time generation proxy
        Subject subject = (Subject) Proxy.newProxyInstance(
        cls.getClassLoader(), cls.getInterfaces(), ds);
        subject.request();
    }
}

Example 2:


package com.langsin.dynamicproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.List;
import java.util.Vector;
public class VectorProxy implements InvocationHandler
{
    private Object proxyobj;
    public VectorProxy(Object obj){
        proxyobj = obj;
    }
    public static Object factory(Object obj){
        Class<?> cls = obj.getClass();
        return Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), new VectorProxy(obj));
    }
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{
        System.out.println("before calling " + method);
        if (args != null){
            for (int i = 0; i < args.length; i++){
                System.out.println(args[i] + "");
            }
        }
        Object object = method.invoke(proxyobj, args);
        System.out.println("after calling " + method);
        return object;
    }
    @SuppressWarnings("unchecked")
    public static void main(String[] args){
        List<String> v = (List<String>) factory(new Vector<String>(10));
        v.add("New");
        v.add("York");
        System.out.println(v);
        v.remove(0);
        System.out.println(v);
    }
}

Example 3,


package com.langsin.dynamicproxy;
public interface Foo{
    void doAction();
}
package com.langsin.dynamicproxy;
public class FooImpl implements Foo{
    public FooImpl(){
    }
    public void doAction(){
        System.out.println("in FooImp1.doAction()");
    }
}
package com.langsin.dynamicproxy;
public class FooImpl2 implements Foo{
    public FooImpl2(){
    }
    public void doAction(){
        System.out.println("in FooImp2.doAction()");
    }
}
package com.langsin.dynamicproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class CommonInvocationHandler implements InvocationHandler{
    //Dynamically executes an object that requires a callback
    private Object target;
    //Support for constructor injection
    public CommonInvocationHandler(){
    }
    //Support for constructor injection
    public CommonInvocationHandler(Object target){
        setTarget(target);
    }
    /**
     *
     * using setter Methods the injection
     *
     * @param target
     *
     */
    public void setTarget(Object target){
        this.target = target;
    }
    /**
     *
     * call proxy The method specified in method , and pass in a list of parameters args
     *
     * @param proxy
     *            The type of the proxy class, such as defining the correspondence method Proxy interface
     *
     * @param method
     *            The proxied method
     *
     * @param args
     *            The parameter that invokes the proxied method
     *
     * @return
     *
     * @throws java.lang.Throwable
     *
     */
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{
        return method.invoke(target, args);
    }
}
package com.langsin.dynamicproxy;
import java.lang.reflect.Proxy;
public class Demo{
    public static void main(String[] args){
        //1. General dynamic proxy implementation < br / >         CommonInvocationHandler handler = new CommonInvocationHandler();
        Foo f;
        //2. Interface implementation 1
        handler.setTarget(new FooImpl());
        //Method parameters: proxy class, proxy class implementation of the interface list, proxy class processor
        //Associate the proxy class, the interface method in the proxy class, and the processor. When the interface method in the proxy class is called, it is automatically distributed to the invoke method of the processor
        //If the proxy class does not implement the specified interface list, an illegal parameter exception
is thrown         f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
        new Class[] { Foo.class },
        handler);
        f.doAction();
        //3. Interface implementation 2
        handler.setTarget(new FooImpl2());
        f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
        new Class[] { Foo.class },
        handler);
        f.doAction();
    }
}

Due to my limited literary talent, so most of the content is code, please forgive ^_^


Related articles: