JDK dynamic proxies and CGLIB proxies

The proxy in Spring AOP can be created in two ways:

  • JDK proxy (dynamic proxy): The JDK proxy creates a new proxy object by implementing interfaces of the target object and delegating method calls
  • CGLIB proxy: The CGLIB proxy creates a new proxy object by extending the target object and delegating method calls

Let's look at these proxy mechanisms and how they differ in the following table:

JDK proxy CGLIB proxy

It is built in JDK.

It is a custom-developed library.

JDK proxy works on the interface.

CGLIB proxy works on subclassing. This is used when the interface is not present.

It will proxy all interfaces.

It cannot work when the method and class are final.

From Spring 3.2, the CGLIB library is packaged with Spring Core, so there's no need to include this library separately in our application.
From Spring 4.0, the constructor of the proxied object will not be called twice, as the CGLIB proxy instance will be created via Objenesis.

By default, Spring will try to use the JDK dynamic proxy if the class of the target object implements the interface; if the class of the target object does not implement any interface then Spring will create a proxy using the CGLIB library.

If the class of the target object implements an interface and it is injected as a concrete class in another bean, then Spring will throw an exception: NoSuchBeanDefinitionException. The solution to this problem is either to inject through the interface (which is a best practice) or to annotate the injection with Scope(proxyMode=ScopedProxyMode.TARGET_CLASS). Then Spring will create a proxy object using the CGLIB proxy. This configuration disables Spring's use of JDK proxies. Spring will then always extend concrete classes, even if an interface is injected. The CGLIB proxy uses the decorator pattern to weave advice to the target object by creating a proxy:

JDK dynamic proxy and CGLIB proxy

Creating a proxy would be able to delegate all calls to a method to interceptors (advice). However, once a method call reaches the target object, any internal method call made within that target object is not going to be intercepted. So, any method call within the object reference would not result in any advice execution. In order to solve this, either refactor the code so that direct self-invocation doesn't happen or use AspectJ weaving. To solve this in Spring, we need to set the expose a proxy property to true and use AopContext.currentProxy() to make self-invocation.

Spring recommends using the JDK proxy wherever possible. Hence, try to implement the abstraction layer almost everywhere in your application so that the JDK proxy will be applied when the interface is available and we have not explicitly set it to use the CGLIB proxy only.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset