Spring Dependency Injection Demystified Part 1: Proxying

Christopher Anatalio
Javarevisited
Published in
6 min readFeb 23, 2021
Spring Proxying in Detail

It’s very common to refer to some Spring features as “magic.” How else could you add functionality like caching at the method level with nothing but a single annotation? Magic!✨ ✨ ✨

Proxying Technologies 🖥 ➡️ 🖥

Over time, I’ve come to learn the names of some of the magic ✨ that facilitates the amazing features of Spring that drive up the productivity of engineers and light a fire under the velocity of development teams.

JDK Dynamic Proxies and CGLIB.

Proxies in Spring are an implementation of the Proxy design pattern and help facilitate the paradigm of Aspect-Oriented Programming.

Benefits of Proxies ➕

  • Provide a surrogate to control access to an object
  • Acts as a wrapper to protect the real component from complexity( i.e. Real component only contains core business logic and not unrelated cross-cutting logic like logging)
  • Provides a level of indirection to support distributed, controlled, or modified access
  • Can act as a placeholder for “expensive to create” objects to allow for lazy creation
  • Can be used to verify permissions before allowing access to secured objects
  • Can inject additional functionality when an object is accessed such as logging, caching, transaction management, etc.

Proxying in Detail 🔎

Let’s take a look at a GIF to see Proxying in action:

Spring Proxying in Action

Nothing like a GIF to get an engaging technical discussion going.

So let’s dive in right in here. Spring is using the interface which your annotated component(Original Class) implements to create a JDK Dynamic proxy(Proxy class) that intercepts every method call made to your component. Each call goes through this proxy on-the-way-in/on-the-way-out.

Step by step 🗒 :

  1. A call to the read method hits the proxy class
  2. The proxy class can execute logic before hitting the actual class such as access control.
  3. The actual concrete class for your custom component is called executing your custom business logic
  4. The custom component then returns the result to the proxy class allowing it to inject logic such as logging
  5. The proxy class returns the result to the original calling class.

JDK Dynamic Proxies ☕️

This is a core class in the Spring AOP Framework package. You can check out the source code on Github.

From the docs 📖 :

JdkDynamicAopProxy is an AopProxy implementation for the Spring AOP framework, based on JDK java.lang.reflect.Proxy dynamic proxies.

Creates a dynamic proxy, implementing the interfaces exposed by the AopProxy that can be used to proxy methods defined in interfaces, rather than classes. Objects of this type should be obtained through proxy factories, * configured by an AdvisedSupport class.

JDK Dynamic Proxies are preferable to CGLIB proxies because they leverage native functionality in the JDK language as opposed to CGLIB that relies on byte-code manipulation. JDK dynamic proxies are also recommended by Spring.

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.

But you always rely on abstractions, not concrete implementations and you always inject interfaces and use constructor injection right? ;)

Martin Fowler will get upset if you don’t. 😢

Proxies help you adhere to SOLID principles. ✅

CGLIB

CGLIB is a byte code generation library that exposes a high-level API to generate/transform JDK byte code. It can be used by AOP, automated testing, data access frameworks, and other paradigms as well. Read more about it here on the CGLIB Wiki on Github.

Some common libraries that use CGLIB are:

Byte code instrumentation allows a framework to manipulate or to create classes JDK compilation. Java classes are linked dynamically at run time, so it’s possible to add new classes to an already running Java program.

CGLIB exposes a series of classes and interfaces that provide functionality such as Callbacks, Filters, Enhancers, Dispatchers, Factories, Handlers, and Interceptors. Read more about CGLIB classes here.

Spring AOP 🍀

Aspect-Oriented Programming (AOP) complements Object-Oriented Programming. Aspects enable the modularization of crosscutting concerns such as transaction management or logging that cut across multiple classes.

This allows you to centralize cross-cutting logic in one place and keep your custom components focused on their specific business logic.

JDK Dynamic Proxies in Detail 🔎

If you debug through your Spring Boot app while it’s running and inspect an injected dependency you can see a Proxy in action.

JDK Dynamic Proxy in Debug Mode

JDK Dynamic AOP Proxy

We can see in the debug frame above, that an Autowired dependency called a TransactionManager contains a JdkDynamicAopProxy class.

JDKDynamicAopProxy Source code 💻

Let’s take a look at the source code of the JDKDynamicAopProxy in detail:

Proxy Method Invocation

When a proxied method is invoked, we pass in the proxy object, the invoked method and the method arguments.

public Object invoke(Object proxy, Method method, Object[] args) {

Spring does some logic to setup the fields we need then we get the interception chain for a method that defines all the proxied logic we need to execute using the getInterceptorsAndDynamicInterceptionAdvice() method in the AdvisedSupport class.

// Get the interception chain for this method.
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

This gives us a list of MethodInterceptors.

Method Interceptors

Intercepts calls on an interface on its way to the target. These are nested “on top” of the target.

MethodInterceptors implement the invoke() method that:

Perform extra treatments before and * after the invocation.

This list of MethodInterceptors defines the proxied logic such as access control, logging or transaction management.

Target Class Method Invocation

After there is no more proxy logic to execute, the AopUtils class is used to actually invoke the method on the target object(Your custom component containing your business logic).

method.invoke(target, args)

Let’s summarize this flow just one more time:

  • Your custom component is proxied by a JDK dynamic proxy
  • A method call comes into the proxy
  • Spring gets the list of MethodInterceptors that define custom proxy logic
  • After that, we call the actual target object method
  • Then return the value to the proxy than to the original caller

This explanation is simplifying the flow but that’s about all there is to it at a high-level!

Questions? Please post them below! ❓

Check out the next article in this series going over the Spring Inversion of Control container coming soon! 🔜

Check out more great Java Ecosystem articles at JavaRevisted ☕️

--

--

Christopher Anatalio
Javarevisited

Platform Advocate for ConsenSys and Technical Author at LinkedIn Learning and Pluralsight