Examples of static and dynamic proxies

There are two main proxy modes: static proxy and dynamic proxy

**1,静态代理:**

比如要在输出“HelloWorld”前打印一个字符串“Welcome”

A:先定义一个接口类
public interface HelloWorldIF {   
    public void print();   
//  public void say();   
} 

B: Define an implementation class of the interface

public class HelloWorldImpl implements HelloWorldIF{   
  
    public void print(){   
        System.out.println("HelloWorld");   
    }   
//  public void say(){   
//      System.out.println("Say Hello!");   
//  }   
}    

C: define a static proxy class

public class StaticProxy implements HelloWorldIF{   
  
    public HelloWorld helloWorld ;   
    public StaticProxy(HelloWorld helloWorld){   
        this.helloWorld = helloWorld;   
    }   
       
    public void print(){   
        System.out.println("Welcome");   
        //相当于回调   
        helloWorld.print();   
    }   
       
//  public void say(){   
//      //相当于回调   
//      helloWorld.say();   
//  }   
}

It can be seen that the static proxy class has a very unpleasant shortcoming: when a method is added to the interface (comments are removed from all the code above), all implementation classes and proxy classes need to be implemented. This increases the complexity of the code. Dynamic proxy can avoid this shortcoming.

2. Dynamic proxy

Compared with ordinary proxies, the biggest advantage of dynamic proxies is that all the methods declared in the interface are transferred to a centralized method (invoke), so that when the number of interface methods is relatively large, we can flexibly deal with There is no need to transfer each method like a static proxy.

Dynamic proxy classes can only proxy interfaces, and all proxy classes need to implement the InvocationHandler class to implement the invoke method. This method is required to call all methods of the proxy interface, and the value returned by the invoke method is an implementation class of the proxy interface.

Agent class:

import java.lang.reflect.InvocationHandler;       
import java.lang.reflect.Method;       
import java.lang.reflect.Proxy;       
//动态代理类只能代理接口,代理类都需要实现InvocationHandler类,实现invoke方法。该invoke方法就是调用被代理接口的所有方法时需要调用的,该invoke方法返回的值是被代理接口的一个实现类       
public class DynamicProxy implements InvocationHandler{       
           
    private Object object;        
    //绑定关系,也就是关联到哪个接口(与具体的实现类绑定)的哪些方法将被调用时,执行invoke方法。   
    //Proxy.newProxyInstance的第三个参数是表明这些被拦截的方法执行时需要执行哪个InvocationHandler的invoke方法   
    public Object bindRelation(Object object){        
        this.object = object;       
        return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(),this);        
    }        
    //拦截关联的这个实现类的方法被调用时将被执行       
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {        
        System.out.println("Welcome");       
        Object result = method.invoke(object, args);        
        return result;       
    }       
      
}

Test class:

public class TestDynamicProxy {       
    public static void main(String[] args){       
        HelloWorld helloWorld = new HelloWorldImpl();       
        DynamicProxy dp = new DynamicProxy();       
        //在这里绑定的是HelloWorld,也就是HelloWorld是被代理接口。所以绑定关系时,需要传递一个HelloWorld的实现类的实例化对象。       
        HelloWorld helloWorld1 = (HelloWorld)dp.bindRelation(helloWorld);        
        helloWorld1.print();        
        helloWorld1.say();       
           
        //helloWorld2将不被拦截   
        HelloWorld helloWorld2 = new HelloWorldImpl();   
        helloWorld2.print();        
        helloWorld2.say();   
           
    }       
}              

Call the print and say methods of the implementation class in the test class, because all the methods of HelloWorld are delegated in the proxy class. So there is no need to implement them one by one like static proxy classes.

Published 17 original articles · Likes0 · Visits 224

Guess you like

Origin blog.csdn.net/weixin_42531204/article/details/105501720