What is the difference between JDK dynamic proxy and CGLib?

JavaReflectionCglibDynamic Proxy

Java Problem Overview


In case of the Proxy Design Pattern, What is the difference between JDK's Dynamic Proxy and third party dynamic code generation API s such as CGLib?

What is the difference between using both the approaches and when should one prefer one over another?

Java Solutions


Solution 1 - Java

JDK Dynamic proxy can only proxy by interface (so your target class needs to implement an interface, which is then also implemented by the proxy class).

CGLIB (and javassist) can create a proxy by subclassing. In this scenario the proxy becomes a subclass of the target class. No need for interfaces.

So Java Dynamic proxies can proxy: public class Foo implements iFoo where CGLIB can proxy: public class Foo

EDIT:

I should mention that because javassist and CGLIB use proxy by subclassing, that this is the reason you cannot declare final methods or make the class final when using frameworks that rely on this. That would stop these libraries from allowing to subclass your class and override your methods.

Solution 2 - Java

Differences in functionality

  • The JDK proxies allow to implement any set of interfaces while subclassing Object. Any interface method, plusObject::hashCode, Object::equals and Object::toString is then forwarded to an InvocationHandler. Additionally, the standard library interface java.lang.reflect.Proxy is implemented.

  • cglib allows you to implement any set of interfaces while subclassing any non-final class. Also, methods can be overridden optionally, i.e. not all non-abstract methods need to be intercepted. Furthermore, there are different ways of implementing a method. It also offers an InvocationHandler class (in a different package), but it also allows to call super methods by using more advanced interceptors as for example a MethodInterceptor. Furthermore, cglib can improve performance by specialized interceptions like FixedValue. I once wrote a summary of different interceptors for cglib.

Performance differences

JDK proxies are implemented rather naively with only one interception dispatcher, the InvocationHandler. This requires a virtual method dispatch to an implementation which cannot always be inlined. Cglib allows to create specialized byte code what can sometimes improve performance. Here are some comparisons for implementing an interface with 18 stub methods:

            cglib                   JDK proxy
creation 	804.000 	(1.899) 	973.650 	(1.624)
invocation 	  0.002   	(0.000) 	  0.005    	(0.000)

The time is noted in nanoseconds with standard deviation in braces. You can find more details on the benchmark in Byte Buddy's tutorial, where Byte Buddy is a more modern alternative to cglib. Also, note that cglib is no longer under active development.

Solution 3 - Java

Dynamic proxy: Dynamic implementations of interfaces at runtime using JDK Reflection API.

Example: Spring uses dynamic proxies for transactions as follows:

enter image description here

The generated proxy comes on top of bean. It adds transnational behavior to the bean. Here the proxy generates dynamically at runtime using JDK Reflection API.

When an application is stopped, the proxy will be destroyed and we will only have interface and bean on the file system.


In the above example we have interface. But in most of implementation of interface is not best. So bean does not implement an interface, in that case we uses inheritance:

enter image description here

In order to generate such proxies, Spring uses a third party library called CGLib.

CGLib (Code Generation Library) is built on top of ASM, this is mainly used the generate proxy extending bean and adds bean behavior in the proxy methods.

Examples for JDK Dynamic proxy and CGLib

Spring ref

Solution 4 - Java

From Spring documentation :

> Spring AOP uses either JDK dynamic proxies or CGLIB to create the > proxy for a given target object. (JDK dynamic proxies are preferred > whenever you have a choice). > > If the target object to be proxied implements at least one interface > then a JDK dynamic proxy will be used. All of the interfaces > implemented by the target type will be proxied. If the target object > does not implement any interfaces then a CGLIB proxy will be created. > > If you want to force the use of CGLIB proxying (for example, to proxy > every method defined for the target object, not just those implemented > by its interfaces) you can do so. However, there are some issues to > consider: > > final methods cannot be advised, as they cannot be overriden. > > You will need the CGLIB 2 binaries on your classpath, whereas dynamic > proxies are available with the JDK. Spring will automatically warn you > when it needs CGLIB and the CGLIB library classes are not found on the > classpath. > > The constructor of your proxied object will be called twice. This is a > natural consequence of the CGLIB proxy model whereby a subclass is > generated for each proxied object. For each proxied instance, two > objects are created: the actual proxied object and an instance of the > subclass that implements the advice. This behavior is not exhibited > when using JDK proxies. Usually, calling the constructor of the > proxied type twice, is not an issue, as there are usually only > assignments taking place and no real logic is implemented in the > constructor.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionKDjavaView Question on Stackoverflow
Solution 1 - JavaraphaëλView Answer on Stackoverflow
Solution 2 - JavaRafael WinterhalterView Answer on Stackoverflow
Solution 3 - JavaPremrajView Answer on Stackoverflow
Solution 4 - JavaTaras MelnykView Answer on Stackoverflow