SoFunction
Updated on 2025-04-10

Detailed explanation of Java static proxy and dynamic proxy

Java Static Proxy and Dynamic Proxy

  • The proxy mode mainly has two implementation methods: static proxy and dynamic proxy.

Static proxy

  • It means that the proxy class required by the program before it is run has been created.
  • Usually, both proxy classes and target classes need to implement the same interface
  • The proxy class maintains the reference to the target class internally. It expands the logical function of the target class by adding functions to the proxy class without changing the target class. The real business logic is still implemented by the target class. The proxy class only calls the relevant methods of the target class, which conforms to the principle of opening and closing.
  • Generally, it is necessary to create proxy classes and interfaces for each target class, which may cause a significant increase in the number of classes.
  • Usually, once the interface is modified, both the proxy class and the target class need to be modified, and the code coupling degree is high.

Example

interface

public interface ILogin {
    void doLogin();
}

Target class

public class UserLogin implements ILogin {
  @Override
  public void doLogin(){
      ("User Login Logic");
  }   
}

Agent class

public class UserLoginProxy implements ILogin {
  private UserLogin mUserLogin;
  public UserLoginProxy() {
    mUserLogin = new UserLogin();
  }
  @Override
  public void doLogin(){
    //...
    ("Before login logic");
    //The real business logic is still implemented by the target class    ();
    ("Logistics after login");     
    //...
  }
}

use

	public static void main(String[] args){
     //
     ILogin iLogin = new UserLoginProxy();
     ();
	}

Dynamic Agent

  • Dynamic proxy refers to dynamically creating proxy objects through reflection mechanism and other technologies when the program is running.
  • Dynamic proxy based on interfaces, usually implements dynamic proxy through classes and interfaces
  • Dynamic class-based proxy, such as using CGLIB (Code Generation Library, a powerful Java bytecode generation library)
  • InvocationHandler calls the processor, which is an interface with an invoke method
  • By using Proxy#newProxyInstance to create a proxy implementation class for the specified interface. When any method of the proxy object is called, the InvocationHandler#invoke method will be called. You can get the passed parameters, annotations, etc. in this method.
  • Only dynamic proxy based on interfaces can be implemented, because Java is single-inherited, and it has inherited the Proxy class when it dynamically generates the $ProxyX proxy class.
  • It can reduce the number of classes, reduce the workload, and has high flexibility. It can dynamically create proxy objects for different delegate classes at runtime.
  • Reduce dependence on business interfaces, reduce coupling, and facilitate post-maintenance. It can be used to implement AOP-oriented programming, such as adding logging, monitoring performance, and permission checking control before and after a logical function.
  • Because reflection is used, it will consume certain performance during operation
private InvocationHandler mInvocationHandler = new InvocationHandler() {
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            //target is the target class object            Object result = (target,args);
            //
            return result;
        }
    };
//Method 1//Create the Class object of the proxy class, parameters (ClassLoader class loader, Class<?>)Class&lt;?&gt; proxyClass = ((), );
//Instantiate the proxy object through reflectionToast toastProxy = (Toast) ().newInstance(mInvocationHandler);
//Method 2 is a simplified version of Method 1. The internal code logic of newProxyInstance is basically the same as Method 1.//Create a proxy object directly, parameters (ClassLoader class loader, Class<?>[], InvocationHandler)Toast toastProxy2 = (Toast) ((),new Class&lt;?&gt;[]{}, mInvocationHandler);

Example

interface

public interface ICalculator {
    int add(int a, int b);
    int minus(int a, int b);
}

Target class

public class Calculator implements ICalculator {
    @Override
    public int add(int a, int b) {
        return a + b;
    }
    @Override
    public int minus(int a, int b) {
        return a - b;
    }
}

Dynamic proxy processing class

  public class CalculatorInvocationHandler implements InvocationHandler {
      private Object target;
      public CalculatorInvocationHandler(Object target) {
           = target;
      }
      @Override
      public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
          // You can add some logic before the method is called          Object result = (target, args);
          // You can also add some logic after the method call          return result;
      }
  }

use

//Target classICalculator calculator = new Calculator();
//Proxy classICalculator proxyCalculator = (ICalculator) (
        ().getClassLoader(),
        ().getInterfaces(),
        new CalculatorInvocationHandler(calculator)
);

This is the end of this article about detailed explanations of Java static proxy and dynamic proxy. For more related Java static and dynamic proxy content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!