A Brief Analysis of the Principle of JDK Dynamic Agent

A Brief Analysis of the Principle of JDK Dynamic Agent


Previously, I wrote an article describing the use of JDK dynamic and static proxies. If you forget the basic usage, you can quickly recall it: 5 minutes to understand Java static and dynamic proxies .This article mainly introduces the principle of JDK dynamic proxy

1. What is dynamic?

To answer this question, the key is to understand the meaning of the two words dynamic. Before understanding this, you need to know the most basic static meaning.

  1. Let's start with the first small question: What is static?

    Static, as the name implies, is a static state.Static-modified static variables in Java, for example, cannot be changed, such as class files that we compile after writing code, and they have one thing in common: ** Once created, they cannot be modified, and they will remain in this state if you want to change or add something new,Each time you need to do it again manually. **This is also the disadvantage of static proxies: if I want to proxy a new interface, I have to rewrite the code, and the rewritten code is structurally mostly duplicated with the previous code.To say the advantage, it may be simple and understandable.

  2. Let's answer the second little question, What is dynamic?

    Dynamic, which is quite understandable. To put it plainly, the state is not unchanged. It will change according to the situation, such as the dynamic planning in the algorithm. The latter state will be affected by the former state. This idea is a bit like what we often say "see the situation".When we look back at the previous static state, we can see that it has a huge advantage - flexibility and rigidity. See what happens before you do it, not what you think about at first.

2. What is dynamic proxy?

Understanding the first big question, What is dynamic?Then let's talk about what dynamic proxy is. Actually, dynamic proxy is a dynamically generated proxy object. If you find this difficult to understand, let's first look at what our own handwritten static proxy looks like:

Static Proxy Object:

//Static Proxy Object (Enhancement of Target Object)
public class SubjectProxy implements Subject{
    //Actual Target Object
    private Subject target;
    //Construction method
    public SubjectProxy(Subject target){
        this.subject=subject;
    }
	//Enhanced Method
    public void request() {
        //pre-processing
        System.out.println("PreProcess");
        //Method of the actual target object
        target.request();
        //Postprocessing
        System.out.println("PostProcess");
    }
}

Actually, the dynamically generated proxy object is very similar to our own handwritten static proxy, but is only dynamically generated by JDK

Let's first see how we normally use dynamic agents:

1. Interface implemented by the target object

public interface Subject {
    void request();
}

2. Target Object

public class SubjectImpl implements Subject{
    @Override
    public void request() {
        System.out.println("Target object handles request!");
    }
}

3. Proxy processor object (implements InvocationHandler interface)

public class ProxyHandler implements InvocationHandler {
    //Actual Target Object
    private Subject subject;//Handle holding the real target object

    public ProxyHandler(Subject subject) {
        this.subject = subject;
    }

    //Enhanced method logic
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //pre-processing
        System.out.println("PreProcess");
        Object result = method.invoke(subject,args);
        //Postprocessing
        System.out.println("PostProcess");
        return result;
    }
}

4. Test Classes

public class Demo {
    public static void main(String[] args) {
        // Target Interface
        Subject subject = new Subject();
        // Proxy Processor
        ProxyHandler handler = new ProxyHandler(subject);
        // Generating dynamic proxy objects
        Object proxy = Proxy.newProxyInstance(loader,
                new Class[]{Cook.class, Driver.class},
                handler);
		// Method to invoke dynamic proxy object
		proxy.request();
    }
}

If you execute the above code yourself, you will find that they all have the same results.At the code level, that is, the request() method in the ** static proxy class is the same as the invoke()** method implemented by the proxy processor. In conjunction with this conclusion, let's see what a dynamic proxy might look like:

//Dynamic Proxy Object (Enhancement of Target Object)
public class &Proxy0 extend Proxy implements Subject{
    // Target Processor (actually in the parent Proxy, here in the subclass for ease of understanding)
    InvocationHandler invocationHandler;
    // Construction method of dynamic proxy
    public &Proxy0(InvocationHandler invocationHandler) {
        this.invocationHandler = invocationHandlerï¼›
    }
	//Enhanced Method
    public void request() {
        invocationHandler.invoke();
    }
}

For your convenience, I'll take the code of the static proxy above and compare it:

//Static Proxy Object (Enhancement of Target Object)
public class SubjectProxy implements Subject{
    //Actual Target Object
    private Subject target;
    //Construction method
    public SubjectProxy(Subject target){
        this.subject=subject;
    }
	//Enhanced Method
    public void request() {
        //pre-processing
        System.out.println("PreProcess");
        //Method of the actual target object
        target.request();
        //Postprocessing
        System.out.println("PostProcess");
    }
}

3. Summary

Comparing slightly, we can see that the difference is not very big. The biggest difference is that dynamic proxy, on the basis of static proxy, extracts the implementation logic of the enhanced methods in static proxy class, called InvocationHandler interface, which allows our apes to write the enhanced logic on their own outside in an Interface-oriented way.Dynamic proxy objects also implement the interface of the target object just like static proxy objects, so the impact on code is very small when we are programming interface-oriented.

The above is a brief analysis of some basic principles, which will be supplemented later. If you have questions, please leave a message to discuss

Tags: Java AOP Proxy

Posted on Fri, 03 Sep 2021 12:39:35 -0400 by Duodecillion