Dynamic proxy may seem like a fancy term, but it’s not that complicated and is easy to understand literally. Dynamically proxying, you can guess what it means, dynamically proxying something at run time, proxying it to do something else. Without getting to the bottom of what this dynamic proxy really means, let’s use a vivid example to understand what it does.

A case in point

A programmerDeveloperHe can develop code, he can debug debug.



There are many categories of programmers, including Java programmersJavaDeveloper, he can develop Java code, he can debug Java code.



But there’s a programmer named Zack who prays a little bit before he starts, so that his code doesn’t have bugs.

Zack’s psychic skill is an acquired one. No other programmer has it. While it is possible to define a programmer with this feature, there are thousands of programs with all sorts of messy features. When are we going to be able to define it so that it doesn’t leak?

There is no need to define him, because he is made, and we should implement this feature during the programmer’s formative years, not before he is born.

So let’s see how the code works, right



If Zack were just an ordinary Java programmer, his development would be

Zack is coding java

Zack is debugging java

But the real Zack is praying for the code! Zack is coding Java Zack’s have no bug! No need to debug!

Proxy.newProxyInstance()

Review the use of dynamic proxies above. Generate an instance object, and then use the Proxy newInstance method to generate a Proxy object for this instance object.



Here is a very critical person, and one that few people understand. Why pass zack’s class load and Zack’s interface?

Notice that zackProxy is of type Developer interface, not an implementation class. Because the objects zack generates after being proxied do not belong to any of the implementation classes of the Developer interface. But it is based on the Developer interface and Zack’s classloading agent.

Look at the interface definition for newProxyInstance()



What exactly do these three parameters mean

  • Loder, the class loader of choice. Since zacks are propped, the class loader that loads zacks is typically used.
  • Interfaces, which can be multiple, are implemented by the propped class.
  • H, a method that binds the proxy class.

Loders and interfaces basically determine what kind of class this is. H is the InvocationHandler that determines what functionality is added to the proxy class. So the whole point of dynamic proxy is this InvocationHandler.

InvocationHandler



The InvocationHandler function is that when the original method of the proxy object is called, the binding executes a method that is defined in the InvocationHandler and returns the result of the original method.

The InvocationHandler receives three arguments

  • Proxy: instance object after proxy.
  • Method, the method by which the object is called.
  • Args, the argument when called.

In the example above,



If the last return statement is changed to

return method.invoke(proxy, agrs);Copy the code

Invoke is not a Zack object, but a proxy object. Based on the above instructions, guess what happens? Yeah, it’s going to loop over and over. Because proxy is the object of the proxy class, when the object method is called, the InvocationHandler will be triggered, and the InvocationHandler will call the object in proxy again, so the call will be repeated. Also, the proxy corresponding method is not implemented. So it’s a loop that keeps reporting errors

Principle of dynamic proxy

Through the above explanation, I believe that you have a deep understanding of the use of dynamic proxy. That dynamic proxy is exactly how to achieve it, let’s look at the source code where the key.

There are several such paragraphs in the newProxyInstance() release.



It’s basically copying out the interfaces, and using those interfaces and the class loader, getting this proxy class CL. We then use reflection to copy the constructor of the proxy Class (this code is in the getConstructor0 method of the Class), and then use the constructor to create an object and bind the object with InvocationHandler.

Application scenarios of dynamic proxy

The advantage of dynamic proxies, as we can see from examples, is that they are flexible and can be used at run time to access methods that change classes without having to define them up front.

Dynamic proxies are something we don’t usually write by hand, but we use them a lot. Annotations used in Spring projects, such as @bean for dependency injection, @AutoWired, @Transactional, etc., are useful, in other words, AOP for Srping (faceted programming).

The use of this scenario is the best place to land a dynamic proxy, to be very flexible in a class, in a method, in a code point to get what we want, which is the content of a dynamic proxy. So in the next article we’ll take a closer look at exactly how Spring AOP uses dynamic proxies.