In the previous post I elaborated on the way Spring supports pooling. In this article I’d like to cover some performance characteristics, the ability to provide insight in the statistics of the pool we’ve previously configured and the way we can use the TargetSource we discussed previously to implement hotswapping.
Performance overhead
Okay, let’s get this out of the way. When you start introducing AOP in your application (be it Spring AOP, AspectJ, JBoss AOP or whatever other AOP library), you are likely to run into a performance hit! There’s no way around it. Somehow the AOP framework needs to be able to add the additional behavior (advices) to the program flow. Spring is using proxies to do the trick. I don’t want to spend too much time on this, so let’s get down to the numbers immediately. I’ve implemented a small test that simulates the following situations:
- PortalManager in combination with a new DocumentParser per request
- PortalManager in combination with a pooled DocumentParser
Scenario 1) on an iMac G5 uses approximately 200 milliseconds for 1 mln calls. The second scenario (so with pooling added that is) takes somewhat over 10 times as long (2100 milliseconds to be precise).
So to conclude: yes, pooling adds overhead (although the overhead is probably for 50% caused by the AOP framework)! That’s why in the previous post I already stressed that pooling should be applied carefully! For helpers that take a really long time to instantiate it can provide help; for simple helpers however you should probably just wire them as prototypes and go with that. If you really need pooling (and this also holds for a lot of the other coarse-grained AOP functionality Spring provides) you shouldn’t care too much about the small overhead since it removes a lot of code-tangling and has all the other benefits AOP offers you (and which I won’t start a discussion about that here) and secondly, the operations involved might even deal with databases, JMS, XML parsing which take way longer than the overhead of AOP anyway.
Mixins to provide insight into the pooling statistics
Okay, there you have it
, AOP adds overhead. Let’s get down to something more interesting: the ability to get insight into the pooling statistics. For management purposes it might be good to get some detail on how many objects are in the pool. The Commons Pool has these statistics available for your, but since we’re transparently introducing pooling behavior, we’re not really able to get to the information without some dirty hacks. That’s why we’re going to introduce the statistics information to our pooled class! We’re going to do this using a mixin. This is hopefully the last time I’m using this awful buzzword in this post. From now on I’ll talk about the ‘introduction of new behavior’.
Spring features the org.springframework.aop.target.PoolingConfig interface which has methods like getActiveCount(), getIdleCount() and getMaxSize(). After we’re done with the magic which is coming in a minute, we’ll be able to do the following with our pooled DocumentParser:
class ParserMonitor {
private PoolingConfig poolingConfig;
void setPoolingConfig(PoolingConfig poolingConfig) {
this.poolingConfig = poolingConfig;
}
}
<bean id="documentParserTarget"
class="example.DocumentParser"/>
<bean id="documentParser"
class="org.sprfr.aop.framework.ProxyFactoryBean">
<property name="targetSource">
<bean class="org.sprfr.aop.target.CommonsPoolTargetSource">
<property name="targetBeanName"
value="documentParserTarget"/>
</bean>
</property>
<!-- some additional stuff -->
</bean>
<bean id="monitor" class="example.ParserMonitor">
<property name="poolingConfig" ref="documentParser"/>
</bean>
The documentParser bean definition is the same as the definition from the last post..
But hey! This means that somehow, the DocumentParser now also implements the PoolingConfig interface. If you look closely, the document parser is passed to the setPoolingConfig() method that takes a PoolingConfig, not a DocumentParser.
Wiring the introduction
The above is what we call an introduction of extra behavior. Through the use of AOP, we’re able to let a class implement an extra interface in a dynamic way. This means, at compile time, the class does not implement this interface but at runtime (when it’s configured using a ProxyFactoryBean) it does!
The configuration is pretty simple. First we wire the target source:
<bean id="poolingTargetSource" class="org.sprfr.aop.target.CommonsPoolTargetSource"> <property name="targetBeanName" value="documentParserTarget"/> </bean>
The target source has a getter for the advisor that produced the introduction. It’s a bit too much to go into this in detail, so let’s just assume we need it:
<bean id="poolingConfigMixin" class="org.sprfr.beans.factory.config.MethodInvokingFactoryBean"> <property name="targetObject" ref="target"/> <property name="targetMethod" value="getPoolingConfigMixin"/> </bean>
The last thing we need to do is wire the proxy factory bean. This resembles the way we did it in the first part of the series of posts on instance management. This however includes the poolingConfigMixin bean as part of the interceptors.
<bean id="documentParser" class="org.sprfr.aop.framework.ProxyFactoryBean"> <property name="targetSource" ref="target"/> <property name="proxyInterfaces" value="com.interface21.pooling.DocumentParser"/> <property name="interceptorNames" value="poolingConfigMixin"/> </bean>
After we’ve added this to our context, we’ll be able to let the ParserMonitor from the snippet above inspect the statistics of our pool. Using Spring’s JMX features we can also for example expose the monitor to a JMX MBeanServer to inspect it using JMX. Pretty cool stuff all without changing a single line of code in our application. This functionality is by the way all provided by AOP. If you’re interested in the concepts behind all of this, you should definitely read some more about AOP, advisors and introductions.
Caution!
As mentioned all over the place in the reference manual as well, you should not just go and pool all the objects in your context just for fun. It DOES provide overhead
Hot-swapping your beans
So let’s see if the target sources can provide us with some other nice functionality. Suppose (in the portal we’ve previously discussed) we actually have two backends, one that takes all the requests and the other one that acts as a fallback in case the first one somehow falls over.
Let’s consider the portal manager:
class PortalManager {
void setDocumentParser(DocumentParser parser) {
this.parser = parser;
}
void setPortalBackend(PortalBackend backend) {
this.backend = backend;
}
PortalDocument getPortalDocument(String query) {
InputStream is = backend.query(query);
return parser.parse(is);
}
}
We’ve seen the DocumentParser before, but this time we’re more interested in the PortalBackend which is communicating with the backend that provides the results for a specific query. Let’s first wire the two backends:
<bean id="primaryBackend" class="example.PortalBackendImpl"> <property name="url" value="http://10.0.0.2/path"/> </bean> <bean id="secondaryBackend" class="example.PortalBackendImpl"> <property name="url" value="http://10.0.0.3/path"/> </bean>
Using the ‘normal’ DI way of configuring things, we can only wire one backend to the PortalManager. Using a target source, we’ll now create a small indirection that helps us switch to the second backend if the first one falls over.
<bean id="swappingBackendTargetSource" class="org.sprfr.aop.target.HotSwappableTargetSource"> <constructor -arg ref="primaryBackend"/> </bean>
Using constructor injection, we’re specifying the initial target. Now, we wire the ProxyFactoryBean with the newly created target source, just as we did with the poolingg target source:
<bean id="portalBackend" class="org.sprfr.aop.framework.ProxyFactoryBean"> <property name="targetSource" ref="swappingBackendTargetSource"/> </bean>
and we inject the proxy (which is going to retrieve the PortalBackend from the target source for us) into the PortalManager:
<bean class="example.PortalManager"> <property name="portalBackend" ref="portalBackend"/> </bean>
So the portal manager is done. Swapping the primary backend out and let the secondary backend pick up all the requests is pretty easy. The target source (with which we’ve configured the target using constructor injection) features a method to change the target called swap(). If we have a handle to the application context, we could easily do the following:
ApplicationContext ctx;
HotSwappableTargetSource hsts =
(HotSwappableTargetSource)ctx.getBean(
"swappingBackendTargetSource");
Object secondaryBackend =
ctx.getBean("secondaryBackend");
hsts.swap(secondaryBackend);
All calls from now on are redirected to the new target we’ve specified (using the swap() method). You don’t have to worrry about threading, all the stuff necessary to swap out the old object for the new one are synchronized.
Now for the falling over of the first backend. We wouldn’t want to program this into our PortalManager. Let’s assume the PortalBackend throws a ConnectException when it somehow has gone out of order. Using a ThrowsAdvice, we’ll transparently swap out the old backend and replace it with the new one:
class BackendNotAvailableThrowsAdvice
implements ThrowsAdvice {
boolean primaryUsed = true;
// other fields ommitted
public void setPrimaryBackend(PortalBackend primary) {
this.primary = primary;
}
public void setSecondaryBackend(PortalBackend secondary) {
this.secondary = secondary;
}
public void setSwappingBackendTargetSource(
HotSwappableTargetSource) {
this.targetSource = targetSource;
}
void afterThrowing(Throwable exception) {
if (exception instanceof ConnectException) {
Object newTarget = primaryUsed ? secondary : primary;
targetSource.swap(newTarget);
}
}
}
After we’ve wired up the advice, we’ll still get a ConnectException after the backend falls over (we can’t swallow exceptions in a ThrowsAdvice), but the next call will be redirected to the new backend and hopefully succeed.
<bean id="portalBackend" class="org.sprfr.aop.framework.ProxyFactoryBean"> <property name="targetSource" ref="swappingBackendTargetSource"/> <property name="interceptorNames" value="backendThrowsAdvice"/> </bean> <bean id="backendThrowsAdvice singleton="true" class="example.BackendNotAvailableAdvice" autowire="byName"/>
Note: 1) the advice is a singleton since we’re keeping state in it and 2) we’re using autowiring here (by name, so the beans that are named according to the corresponding method will have to be available in the context
Again, this is not the most sophisticated construction out there since we’ll still get a connect exception if one of the backends falls over. Using an ordinary MethodInterceptor we change this. If you’re interested, I can cover that in a later entry.
Conclusion
Well, we’ve seen that AOP and pooling adds overhead, but that’s no surprise (at least, not to me). You’ll have to remember when using Spring’s AOP functionality and stuff like pooling that it’s all meant to take away the burden to code that infrastructural tidbits yourself and to have it all tangle across the code that really matters: the code that actually implements the customer’s needs. Secondly, it’s important to note that loads of J2EE apps communicate with an external resource and this probably takes WAY more time than executing AOP and pooling stuff. So remember this: don’t go and implement a ThrowsAdvice to catch IllegalArgumentExceptions that occur through your application! You’re probably better off implementing some kind of top-level exception handler here (like the HandlerExceptionResolver< /a> for web applications) or using AspectJ.
We’ve also reviewed a way to get insight into the statistics of our pool. Mixins are pretty powerful but also a technique you shouldn’t apply all over the place. To read more about mixins and AOP in general I recommend Ramnivas Laddad’s book or the one by Adrian Colyer and others.
Then there’s hot swapping. Out-of-the-box Spring provides features like this, and I hope you gained some insight into some of the things you can do will all those features. You should however not be afraid to go and implement your own TargetSource, ThrowsAdvice or stuff like that. It’s not that hard, it just takes some creativity and a bit of knowledge about the API.
Next time I’ll shortly review the other target sources available.

[...] This post is by the way followed up by a second one on performance, mixins and hotswapping. [...]
Couldn’t you use around advise to trap the ConnectException and retry with the newly swapped target?
In the first part of the article you say “The target source has a getter for the advisor that produced the introduction. It’s a bit too much to go into this in detail, so let’s just assume we need it:” Where would be a good placed to into more detail? Is this covered in a book? The Spring Reference Manual doesn’t go into much detail either.
Bill, the target source interface is covered in more detail in Professional Java Development with the Spring Framework. There’s a chapter on AOP in there which does not only go into the most common use cases but also covers the internal and hooks you can use to extend Spring AOP to your own needs.
About the AroundAdvice, you could actually trap the exception and retry. Instead of a ThrowsAdvice you would have to implement a MethodInterceptor and issue a second methodInvocation.proceed() call if the exception occurs.
forex trading system
forex trading system and you will plumstead that the longest of Alfassi sterres is non-fusible in condense to that
Liberty reserve is a great payment processor and hopefully will be used by more users. I find it hard to sell it for Perfect Money so I created a list of exchangers.
there are some great points in this article now to do more research