Spring
A basic Spring/OpenCms 'getting-started' project: http://www.sendspace.com/file/x2sipm
Contents |
Spring Framework 2.0
Integrating the Spring Framework usually involves definition of a Web Application Context listener-class in web.xml. The Spring Framework already comes with such a listener, org.springframework.web.context.ContextLoaderListener.
<listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
It starts the Spring ApplicationContext/BeanFactory. It might be required to override the context-pararm contextConfigLocation to tell the listener where it can find the configuration file (the default param-value is /WEB-INF/applicationContext.xml).
<context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:/application-context.xml</param-value> <description>Tells Spring where to find its configuration</description> </context-param>
The above example shows how to access an application-context.xml which is a classpath resource (deployed in WEB-INF/lib/*.jar or WEB-INF/classes).
Deployment Restriction
The Spring Framework should be deployed directly to WEB-INF/lib. Defining a context listener requires the listener class to be available during startup of the Web Application. It is inconvenient to deploy listener classes as part of an OpenCms module because all included classes are unavailable to the WebappClassLoader prior to publishing the module. This causes listener initializations to fail and leads to a bootstrap problem. With Tomcat, Web Application startup fails if a single listener fails to initialize. There is an error in the catalina.out log file saying
SEVERE: Error listenerStart SEVERE: Context [...] startup failed due to previous errors
Usually, the localhost_log contains more information including a stack trace.
The obvious workaround for deploying listeners within a module would be to import and publish the module first and define the listener in a second step. Removal of the module requires the reverse order.
Accessing the Application Context
It might be a good idea to supply your own application context class and tell the listener to start it. Your class can keep a static reference of the initialized context instance. You can do that by subclassing org.springframework.web.context.support.XmlWebApplicationContext.
The application context is configured with another context-param. It is read by ContextLoaderListener.
<context-param> <param-name>contextClass</param-name> <param-value>com.acme.spring.AcmeSpringContext</param-value> <description>Tells the Spring ContextListener which class to use</description> </context-param>
The custom contextClass must be available at context start and thus may not be part of a module.
Hibernate Session in View Pattern
If you want to use Hibernate along with Spring you can use the appropriate hibernate filter to manage sessions.
<filter> <filter-name>hibernateFilter</filter-name> <description> Creates sessions and transactions for each mapped request </description> <filter-class> org.springframework.orm.hibernate3.support.OpenSessionInViewFilter </filter-class> </filter>
Map the filter to the OpenCmsServlet.
<filter-mapping> <filter-name>hibernateFilter</filter-name> <servlet-name>OpenCmsServlet</servlet-name> </filter-mapping>
Each request to the OpenCms servlet will be surrounded by a Hibernate session.
This is somewhat suboptimal as the session is created even when it is not required. Your code which requires a session and transactions might not be executed at all. Nevertheless, the Open Session in View pattern is well-known and the easiest solution to the lazy initialization problem which occurs when lazy members of a Hibernate proxy object are accessed after its session has been closed.