Spring Dependency Injection Demystified Part 1: Proxying
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 .
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:
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 🗒 :
- A call to the read method hits the proxy class
- The proxy class can execute logic before hitting the actual class such as access control.
- The actual concrete class for your custom component is called executing your custom business logic
- The custom component then returns the result to the proxy class allowing it to inject logic such as logging
- 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 .
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 , 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 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 .
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 s, s, s, s, ies, s, and s. Read more about .
Spring 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 while it’s running and inspect an injected dependency you can see a Proxy in action.
JDK Dynamic Proxy in Debug Mode
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 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
// Get the interception chain for this method.
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
This gives us a list of .
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 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 ☕️
Want to learn more about Spring Proxies? 🏫
- Spring AOP Docs:
- Checkout the Spring AOP Open Source Repository:
- Oracle JDK Proxies Docs:
- CGLIB Wiki:
Interested in Reactive Programming with Spring?
Interested in Guided Video Learning on Spring? 🏫
Learn how to build a full stack app with Spring Boot and Angular!
See all my other courses at: