At work and online I keep hearing the term "proxy" with respect to enterprise Java development. For example, metrics-spring uses this phrase:
This module does the following things:
Creates metrics and proxies beans which contain methods annotated with @Timed, @Metered, @ExceptionMetered, and @Counted [emphasis mine]
I'm unfamiliar with a lot of the language in the Java ecosystem of frameworks and libraries. I feel like I have a good understanding of what a bean is, but I'm still not clear about how one would proxy a bean.
What does it mean to proxy a bean?
You may also use <aop:scoped-proxy/> between beans that are scoped as singleton, with the reference then going through an intermediate proxy that is serializable and therefore able to re-obtain the target singleton bean on deserialization.
Under the covers, it uses ASM bytecode manipulation framework. Essentially, CGLIB dynamically generates a subclass to override the non-final methods of the proxied class. It is faster than the JDK dynamic proxy approach, which uses Java reflection. CGLIB cannot proxy a final class or a class with any final methods.
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.
JDK Dynamic Proxies allow one to create implementations of Java interfaces at runtime by the means of Reflection. A proxy may be seen as a subject that will forward method calls to target instances and eventually return any result produced by the target instance to the caller.
Typically, you have a bean like
Bean bean = new Bean(); // actually created by the context
With this, you can do anything that the Bean
class declares as behavior (invoke its methods).
There are times where it would be nice if you could, for example, track how long a method invocation takes.
You could do
long start = .. // get start time
bean.invoke();
long end = .. // get end time
// end - start
But doing this for each method invocation sucks. So, instead, patterns, architectures, and styles like Aspect Oriented Programming exist.
Instead of the Bean
above, you'd have
Bean bean = new TimingBean(new Bean()); // again done by the context
where the TimingBean
is a proxy type that extends and implements all the types that Bean
extends and implements. For all intents and purposes it is a Bean
, but it adds a bunch of additional behavior before delegating each invocation to the Bean
object. In this case, it would track how long each of Bean
's method's took to execute.
Basic Spring uses JDK proxies and CGLIB proxies. Here are some differences between them.
It uses this for its scheduling and asynchronous invocations. It uses it for transactional support with databases. It uses it for caching. It even uses it for its Java based container configuration.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With