Faster Spring initialisation
January 12, 2008
Spring is a great framework but it can take a while to startup (often due to other libraries such as Hibernate or EHCache). This can be minimised using Spring’s lazy initialisation.
Mark beans for lazy initialisation by setting the “lazy-init” attribute to “true”. For example:
<bean id="myBean" class="MyBean" lazy-init="true" />
You can also set default-lazy-init=”true” on the “beans” elements (if appropriate).
For web applications, ensure that the Spring dispatcher servlet (org.springframework.web.servlet.DispatcherServlet) is NOT loaded on startup (it automatically initialises controllers and hence dependent beans). You can do this by removing the “load-on-startup” element in web.xml.
Core beans (such as session factories) with many dependecies should generally avoid lazy-init=”true”.
Production environments
In production environments, eager initialisation may be more appropriate. This can be achieved by having a different WAR file for production with the Spring dispatcher servlet loaded on startup. (Ant’s “replace” task can be used to automatically remove commented out XML for the production build). For example:
<servlet>
<servlet-name>test</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<!--@PRODUCTION:UNCOMMENT<load-on-startup>1</load-on-startup>@PRODUCTION:UNCOMMENT-->
</servlet>
Best of both worlds
It is also possible to have a “best of both worlds” approach by loading beans in the background once the application has started up. This means:
- the app starts up as quickly as possible
- for most requests, beans will already be initialised
Code and docs are available at the yojava lab.
Other workarounds
-
Coding to test cases minimise the need for server restarts
-
JavaRebel (and WebLogic 10.3?) can reload classes on the fly
-
Different servlet containers have faster startup times (Jetty? Glassfish?)