Summary of Java dynamic proxy implementation methods

  • 2021-06-29 11:07:22
  • OfStack

An example of how to implement the Java dynamic proxy is given.Share it for your reference, as follows:

Static proxy is almost understood, but the understanding of dynamic proxy is not very thorough. Here, first write down some commonly used dynamic proxy implementation methods, and often look at them in the future for early convergence.

1. JDK implements dynamic proxy

The Proxy.newProxyInstance() method is mainly used, which is officially interpreted as returning a proxy class instance of a specified interface that can assign method calls to the specified call handler.


public interface ISomeService {
  String doFirst();
  void doSecond();
  String doThird();
}
// Target class: The class to be enhanced by the proxy class 
public class SomeServiceImpl implements ISomeService {
  @Override
  public String doFirst() {
    return "AAAbbb";
  }
  @Override
  public void doSecond() {
    System.out.println("SomeServiceImpl : Execute doSecond()");
  }
  @Override
  public String doThird() {
    return "aaa";
  }
}
public class Mytest {
  public static void main(String[] args) {
    ISomeService target = new SomeServiceImpl();
    ISomeService someService = (ISomeService) Proxy.newProxyInstance(
        target.getClass().getClassLoader(),
        target.getClass().getInterfaces(),
        new InvocationHandler() {
          // proxy : Proxy object 
          // method : Target method 
          // args : List of parameters for the target method 
          @Override
          public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            Object result = method.invoke(target, args);
            if(result!=null) {
              result=((String)result).toUpperCase();
            }
            return result;
          }
        });
    System.out.println(someService.doFirst());
    someService.doSecond();
    System.out.println(someService.doThird());
  }
}

2. CGLIB implements dynamic proxy (no interface)

Implementing a dynamic proxy using Proxy from JDK requires that the target class implement the same interface as the proxy class, which cannot be used if no interface exists for the target class.

For classes without interfaces, to create dynamic proxies for them, use CGLIB.The CGLIB dynamic proxy is generated by generating a subclass of the target class, which is enhanced to be the proxy object.Generating a proxy class using CGLIB requires that the target class must be inheritable and therefore not an final class.


// Target class: The class to be enhanced by the proxy class 
public class SomeService {
  public String doFirst() {
    System.out.println("SomeServiceImpl : Execute doFirst()");
    return "AAAbbb";
  }
  public void doSecond() {
    System.out.println("SomeServiceImpl : Execute doSecond()");
  }
}
// Note: Use Cglib Dynamic proxy, requires target class not to be final Of 
//Cglib Dynamic proxies are enhanced by the principle that subclasses enhance the parent class, so the target class must be inherited 
public class CglibFactory implements MethodInterceptor {
  private SomeService target;
  public CglibFactory() { }
  public CglibFactory(SomeService target) {
    this.target = target;
  }
  public SomeService myCglibCreator() {
    Enhancer enhancer = new Enhancer();
    // Specify the parent class, the target class.because Cglib The principle of dynamic proxy enhancement is that subclasses enhance parent classes 
    enhancer.setSuperclass(SomeService.class);
    // Set Callback Interface Object 
    enhancer.setCallback(this);
    //create() Method is used to create Cglib Dynamic Proxy Object 
    return (SomeService)enhancer.create();
  }
  // Execution condition of callback function: This method is triggered when the proxy object executes the target method 
  @Override
  public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
    Object invoke = method.invoke(target, args);
    if(invoke!=null) {
      invoke=((String)invoke).toUpperCase();
    }
    return invoke;
  }
}
public class Mytest {
  public static void main(String[] args) {
    SomeService target = new SomeService();
    SomeService proxy = new CglibFactory(target).myCglibCreator();
    proxy.doFirst();
  }
}

3. CGLIB implements dynamic proxy (with interface)

Actually, it is almost the same to implement dynamic proxy with CGLIB when there is an interface as with CGLIB when there is no interface.


public interface ISomeService {
  String doFirst();
  void doSecond();
  String doThird();
}
// Target class: The class to be enhanced by the proxy class 
public class SomeService implements ISomeService {
  public String doFirst() {
    return "AAAbbb";
  }
  public void doSecond() {
    System.out.println("SomeServiceImpl : Execute doSecond()");
  }
  @Override
  public String doThird() {
    return "third";
  }
}
// Note: Use Cglib Dynamic proxy, requires target class not to be final Of 
//Cglib Dynamic proxies are enhanced by the principle that subclasses enhance the parent class, so the target class must be inherited 
public class CglibFactory implements MethodInterceptor {
  private ISomeService target;
  public CglibFactory() { }
  public CglibFactory(ISomeService target) {
    this.target = target;
  }
  public ISomeService myCglibCreator() {
    Enhancer enhancer = new Enhancer();
    // Specify the parent class, the target class.because Cglib The principle of dynamic proxy enhancement is that subclasses enhance parent classes 
    enhancer.setSuperclass(ISomeService.class);
    // Set Callback Interface Object 
    enhancer.setCallback(this);
    //create() Method is used to create Cglib Dynamic Proxy Object 
    return (ISomeService)enhancer.create();
  }
  // Execution condition of callback function: This method is triggered when the proxy object executes the target method 
  @Override
  public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
    Object invoke = method.invoke(target, args);
    if(invoke!=null) {
      invoke=((String)invoke).toUpperCase();
    }
    return invoke;
  }
}
public class Mytest {
  public static void main(String[] args) {
    ISomeService target = new SomeService();
    ISomeService proxy = new CglibFactory(target).myCglibCreator();
    System.out.println(proxy.doFirst());
    proxy.doSecond();
    System.out.println(proxy.doThird());
  }
}

More readers interested in java-related content can view this site's topics: Introduction and Advanced Java Object-Oriented Programming, Java Data Structure and Algorithms, Java Operation DOM Node Skills Summary, Java File and Directory Operation Skills Summary, and Java Cache Operation Skills Summary.

I hope that the description in this paper will be helpful to everyone's java program design.


Related articles: