Single Bean Factory per Classloader: A new Spring Pattern
September 18th, 2007 by Oscar HuseyinAfter my blog on Aspects of Spring on a monolithic codebase, lve been searching about the topic and, to my surprise, have not been able to find any posting relating to this or similar issues. Nor have l been able to locate any documentation or papers regarding this aspect of spring usage. Well… l think its time to lay claim to a pattern.
After some thought, lve decided to call it Single Bean Factory per Classloader. And the description of the pattern is:
When constructing a Spring Bean Factory, ensure that you have a single instance of the bean factory per-classloader and you load the spring application context files from a standard location in the classpath.
What does this equate to? Well, lets me describe the pattern by giving an example from the trenches: A J2EE application (EAR) that contains an EJB and Web Module.
In the complex innards of an J2EE Application Server, there are a few truths that we can rely on. One of these truths is that an EAR will have a classloader all to itself. Therefore, all JAR’s packaged at the EAR level will be on the EAR’s classpath *automagically*. The EJB module will always share the EAR’s classloader, in fact, they are deployed as a single JAR in the root of the EAR. Web modules, on the other hand, do have a separate classloader, but the WAR’s classloader will be the EAR’s classloaders child. Therefore, the EAR and the WAR have a parent child relationship w.r.t classloaders.
Why do l need to know this, l hear you ask? Well, its all about scope. As the Single Bean Factory per Classloader pattern suggests, a core principle is the single instance of the Bean Factory per classloader. Therefore the object that constructs the Spring Bean Factory must be on the EAR’s classloader and not on the Web Modules class loader. How do you guarantee this? Package the Bean Factory Singleton wrapper into the EAR level. You can then instantiate the Singleton Bean Factory wrapper from the EJB module or Web Module and you’ll be guaranteed to have a single instance.
Now that we have a clear understanding of “the classloader aspect”, lets talk about the second principle; “load application contexts from a standard location”. This way, you can abstract the dependency aspects of your spring defined components to be managed by the a dependency tool, like Ivy and link them from your components on the classloader. What the hell does this mean? Well, you have not read blog entry Aspects of Spring on a monolithic codebase! For those who have not read it, l’ll summarise. Its real simple; ensure that you have one or many (keep it consistent though) number of “main” spring application context xml files that you stored in a standard location in the JAR, i.e. META-INF/components. That way, the code to find the application context files is generic:
getClass().getClassLoader().getResources("META-INF/components/components.xml");
There you have it. This pattern has the capability to really increase the manageability of your spring based applications. Enjoy.