In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-29 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article mainly shows you the "Spring AOP in JDK and CGLib dynamic agent efficiency which is more", the content is easy to understand, clear, hope to help you solve the doubt, the following let the editor lead you to study and learn "Spring AOP JDK and CGLib dynamic agent which is more efficient" this article.
I. background
During the interview, I was asked: which is the more efficient JDK or CGLib dynamic agent in Spring AOP?
II. Basic concepts
First of all, we know that there are two ways for the underlying implementation of Spring AOP: one is JDK dynamic proxy, and the other is CGLib.
Since Java 1.3, Java has provided dynamic proxy technology, which allows developers to create proxy instances of interfaces at run time, and this technology has been used in many places in Spring.
The JDK dynamic proxy mainly involves two classes under the java.lang.reflect package: Proxy and InvocationHandler. Among them, InvocationHandler is an interface, which can define crosscutting logic by implementing this interface, and call the code of the target class through reflection mechanism, dynamically devaluing crosscutting logic and business logic together.
JDK dynamic proxy has a limitation that it can only create proxy instances for interfaces, but for classes that do not define business methods through the interface, how to create dynamic proxy instances? The answer is CGLib.
CGLib uses the underlying bytecode technology, the full name is: Code Generation Library,CGLib can create a subclass for a class, in the subclass using method interception technology to intercept calls to all parent methods and weave crosscutting logic.
III. The difference between JDK and CGLib dynamic agents
1. The specific implementation principle of JDK dynamic agent:
Create your own call handler by implementing the InvocationHandlet interface
Create a dynamic proxy by specifying a ClassLoader object and a set of interface for the Proxy class
The constructor of the dynamic proxy class is obtained through the reflection mechanism, and its only parameter type is to call the processor interface type.
Create a dynamic proxy class instance through the constructor, and call the processor object as a parameter during construction.
JDK dynamic proxy is an interface-oriented proxy mode, and Spring can do nothing if the proxied target does not have an interface. Spring produces a new anonymous implementation class of the proxied interface through the reflection mechanism of Java and rewrites the enhanced method of AOP.
2. CGLib dynamic proxy:
CGLib is a powerful, high-performance Code production class library, which can dynamically extend java classes at run time. Spring inherits the classes to be dynamically proxied through CGlib, rewrites the methods of the parent class, and realizes aspect-oriented programming in AOP.
3. Comparison between the two:
The JDK dynamic proxy is interface-oriented.
The CGLib dynamic proxy is implemented through bytecode underlying inheritance of the proxy class (sorry to fail if the proxied class is modified by the final keyword).
4. Note when using:
If the object to be proxied is an implementation class, Spring uses the JDK dynamic proxy to complete the operation (Spirng defaults to the JDK dynamic proxy implementation mechanism)
If the object to be proxied is not an implementation class, Spring enforces the use of CGLib to implement dynamic proxies.
IV. Performance comparison of JDK and CGLib dynamic agents-textbook description
Whether we are reading a book or reading an article or searching for a reference answer on my website, we may find the following answer in many cases:
With regard to the performance between the two, the performance of the proxy object created by the JDK dynamic proxy is not very high in the previous JDK version, although the performance of the JDK dynamic proxy object has been greatly improved in the high version, but it is not suitable for all scenarios. It is mainly reflected in the following two indicators:
1. The performance of the dynamic proxy object created by CGLib is much higher than that of JDK dynamic proxy in actual runtime, and some studies have shown that it is about 10 times higher.
2. However, CGLib spends much more time creating objects than JDK dynamic agents. Some studies have shown that there is a gap of about 8 times.
3. Therefore, for the proxy object of singleton or the proxy with instance pool, because there is no need to create proxy objects frequently, it is more suitable to use CGLib dynamic proxy, anyway, it is more suitable for JDK dynamic proxy.
Is the result as described in articles 1, 2 and 3 above? Next, let's do some small experiments and analysis!
Fifth, performance testing
1. First, there are several Java classes
2 、 Target.java
Package com.java.proxy.test;public interface Target {int test (int I);}
3 、 TargetImpl.java
Package com.java.proxy.test;public class TargetImpl implements Target {@ Override public int test (int I) {return I + 1;}}
4 、 JdkDynamicProxyTest.java
Package com.java.proxy.test;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;public class JdkDynamicProxyTest implements InvocationHandler {private Target target; private JdkDynamicProxyTest (Target target) {this.target = target;} public static Target newProxyInstance (Target target) {return (Target) Proxy.newProxyInstance (JdkDynamicProxyTest.class.getClassLoader (), new Class [] {Target.class}, new JdkDynamicProxyTest (target)) } @ Override public Object invoke (Object proxy, Method method, Object [] args) throws Throwable {return method.invoke (target, args);}}
5 、 CglibProxyTest.java
Package com.java.proxy.test;import org.springframework.cglib.proxy.Enhancer;import org.springframework.cglib.proxy.MethodInterceptor;import org.springframework.cglib.proxy.MethodProxy;import java.lang.reflect.Method;public class CglibProxyTest implements MethodInterceptor {private CglibProxyTest () {} public static Target newProxyInstance (Class targetInstanceClazz) {Enhancer enhancer = new Enhancer (); enhancer.setSuperclass (targetInstanceClazz); enhancer.setCallback (new CglibProxyTest ()); return (Target) enhancer.create () } @ Override public Object intercept (Object obj, Method method, Object [] args, MethodProxy proxy) throws Throwable {return proxy.invokeSuper (obj, args);}}
6 、 ProxyPerformanceTest.java
Package com.java.proxy.test;import java.util.LinkedHashMap;import java.util.Map;public class ProxyPerformanceTest {public static void main (String [] args) {/ / create test object Target nativeTest = new TargetImpl (); Target dynamicProxy = JdkDynamicProxyTest.newProxyInstance (nativeTest); Target cglibProxy = CglibProxyTest.newProxyInstance (TargetImpl.class); / / preheat int preRunCount = 10000; runWithoutMonitor (nativeTest, preRunCount); runWithoutMonitor (cglibProxy, preRunCount); runWithoutMonitor (dynamicProxy, preRunCount) / / execute the test Map tests = new LinkedHashMap (); tests.put ("Native", nativeTest); tests.put ("Dynamic", dynamicProxy); tests.put ("Cglib", cglibProxy); int repeatCount = 3; int runCount = 1000000; runTest (repeatCount, runCount, tests); runCount = 50000000; runTest (repeatCount, runCount, tests) } private static void runTest (int repeatCount, int runCount, Map tests) {System.out.println (String.format ("\ n = run test: [repeatCount=%s] [runCount=%s] [java.version=%s] =", repeatCount, runCount, System.getProperty ("java.version")); for (int I = 0; I < repeatCount) ) {System.out.println (String.format ("\ n-test: [% s] -", (I + 1)); for (String key: tests.keySet ()) {runWithMonitor (tests.get (key), runCount, key);}} private static void runWithoutMonitor (Target target, int runCount) {for (int I = 0; I < runCount) Private static void runWithMonitor (Target target, int runCount, String tag) {long start = System.currentTimeMillis (); for (int I = 0; I < runCount; iTunes +) {target.test (I);} long end = System.currentTimeMillis (); System.out.println ("[" + tag + "] Total Time:" + (end-start) + "ms");}}
7. Test results
(1) JDK 1.6
(2) JDK 1.7
(3) JDK 1.8
After many experiments, we can see that on average, the running speed of the JDK dynamic agent has gradually improved. In the lower version, the performance may not be as good as that of CGLib, but running many times in the 1.8 version, we can basically get the same test results, that is, the JDK dynamic agent is faster than the CGLib dynamic agent!
But the applicable scenarios of JDK dynamic agent and CGLib dynamic agent are not the same!
VI. Summary
The final test results are roughly like this. At 1.6 and 1.7, the speed of JDK dynamic agent is slower than that of CGLib dynamic agent, but it is not 10 times the gap in textbooks. In JDK1.8, the speed of JDK dynamic agent is much faster than that of CGLib dynamic agent. I hope that partners can have a target when they encounter this problem!
Spring AOP JDK and CGLib dynamic agent on this knowledge is very important, about the performance comparison between the two after testing experiments already have a preliminary result, and then someone asked you Spring AOP, do not simply say JDK dynamic agent and CGLib these two, it is time to throw out the understanding of the difference between the two, there are points oh!
The above is all the content of this article "which is the more efficient dynamic agent of JDK or CGLib in Spring AOP? thank you for reading!" I believe we all have a certain understanding, hope to share the content to help you, if you want to learn more knowledge, welcome to follow the industry information channel!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.