The basic principle of Java JDK dynamic agent is introduced in detail

JDK dynamic agent details

This paper mainly introduces the basic principle of JDK dynamic proxy, so that we can have a deeper understanding of JDK proxy and know why. Understand the real principle of JDK dynamic proxy and its generation process. In the future, we can write a perfect proxy without checking the demo. Let's start with a simple demo. Subsequent analysis processes rely on this demo to introduce. The example uses jdk1 8 operation.

JDK Proxy HelloWorld

Run the above code to implement a simple JDK proxy.

Agent generation process

We call it JDK dynamic agent every day because this agent class is dynamically generated by JDK during runtime. Before explaining the agent generation process, let's put - dsun misc. ProxyGenerator. The parameter savegeneratedfiles = true is added to the JVM startup parameter. Its function is to help us save the bytecode of the proxy class dynamically generated by JDK to the hard disk and help us view the specific generated proxy content. I use IntelliJ idea. After the proxy class is generated, it is directly placed in the root directory of the project, and the directory structure is called by the specific package name.

The generation process of proxy class mainly includes two parts:

Getproxyclass method entry of proxy class: class loader and interface need to be passed in

Then the getProxyClass0 method is invoked, and the annotations in it are very clear. If the proxy class of the current interface exists, it will be returned directly from the cache. If it does not exist, it can be created through ProxyClassFactory. It is obvious that there is a limit on the number of interface interfaces, which cannot exceed 65535. The specific initialization information of proxyclasscache is as follows:

The specific logic for creating a proxy class is created through the apply method of proxyclassfactory.

The logic in proxyclassfactory includes the creation logic of package name. Call proxygenerator Generateproxyclass generates a proxy class and loads the proxy class bytecode into the JVM.

1. The package name generation logic defaults to com sun. Proxy. If the proxy class is a non-public proxy interface, use the same package name as the proxy class interface. The default class name is $proxy plus a self increasing integer value.

2. After the package name and class name are ready, it is through proxygenerator Generateproxyclass creates proxy bytecode according to the specific incoming interface, - dsun misc. ProxyGenerator. The parameter savegeneratedfiles = true works in this method. If it is true, the bytecode will be saved to the disk. In the proxy class, the logic of all proxy methods is the same. They all call the invoke method of invocationhandler. We can see the specific proxy decompilation results later.

3. Load the bytecode into the JVM through the incoming class loader: defineclass0 (loader, proxyname, proxyclassfile, proxyclassfile. Length);.

We can decompile according to the bytecode of the proxy class and get the following results. HelloWorld has only sayhello method, but there are four methods in the proxy class, including three methods on object: equals, toString and hashcode.

The general structure of the agent includes four parts:

common problem:

1. Tostring() hashcode() equal() method calling logic: if the methods on the three objects are called, they will go through the invocationhandler logic like the processing logic of other interface methods. It can be seen from the bytecode results above. Methods on other objects will not follow the proxy processing logic, but directly follow the method logic on the object inherited by proxy.

2. When the interface contains equals, toString, hashcode methods, like ordinary interface methods, it will follow the invocation handler logic and trigger the method logic based on the logic rewritten by the target object;

3. The interface contains duplicate method signatures, which shall be subject to the incoming order of the interface. Whoever is in front will use whose method. Only one method will be retained in the proxy class, and there will be no duplicate method signatures;

Thank you for reading, hope to help you, thank you for your support to this site!

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>