Demystifying Spring. Section 3: Let’s implement Dynamic Proxy
We discussed Dynamic and CGLib proxies at a higher level in previous article. Let’s implement Dynamic Proxy into our project in this section.
Creating an InvocationHandler
When working with dynamic proxies, we must implement InvocationHandler
interface, which has a single method:
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable;
This method is responsible for handling method invocations on the proxy object. Let’s see what are the arguments of this method.
- proxy: This parameter refers to the proxy object itself. In most cases, we don’t use it directly, as it could lead to infinite recursion if you call methods in proxy object within the
invoke
method. Instead, we call methods in actual target object. - method: A method object that represents the method being invoked on the proxy object. This object contains properties like name, return type and annotations.
- args: Array of arguments passed to the method being invoked. You can access and manipulate these arguments before or after calling the target method on the actual object.
Here is our InvocationHandler
implementation:
We need to provide an object we want to handle through the constructor. In our case a CustomerServiceImpl
object.
The invoke
method intercepts calls on the proxy object, performs actions before and after invoking the actual method on the target
object, and returns the result. This is a common pattern for adding custom behavior like logging, or other aspects to method calls when using dynamic proxies.
Create a Proxy
Now we have a InvocationHandler
, so lets create a Proxy object.
After running Part3Application class, you will get an output similar to this:
Our proxy now handles transactions!
You can see source code for this section here:
Let’s see how to implement same behavior using CGLib proxy in the next section.