Where do I put my beans? What beans? Coffee beans? Java beans? No - Spring beans! When running a servlet container, such as Apache Tomcat, you must define all your java beans in such a way as to facilitate the separation of the live and development system and yet allows you to remain within what is accepted as a “standard approach". There isn’t much advice or documentation online to help with this, so there follows an out-line of collected knowledge absorbed from reading lots of configuration files. When a servlet container starts up, it reads the
/WEB-INF/web.xmlfile which defines the configuration of the servlet. This file is typically a pointer to 2 other files. The first is named
/WEB-INF/myproj-webapp-config.xmland the second is named
/WEB-INF/myproj-servlet-config.xml. Lets take a look at the
After the Java EE header and standard configuration comes the first of the 2 file pointers. The
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation=" http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5" > <display-name>My Project</display-name> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/myproj-webapp-config.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <servlet-name>myproject</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/myproj-servlet-config.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>myproj</servlet-name> <url-pattern>*.html</url-pattern> </servlet-mapping> </web-app>
contextConfigLocationis described in the
/WEB-INF/myproj-webapp-config.xml. This file contains the beans for the application. These are the Java beans that in the most part “do all the work". This file is laid out in a way that separates the business logic from the live application infrastructure. Below is a typical example to help explain this:
The header says that this is a file containing spring beans. It is split into several sections. The first bean (
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <!-- Configuration --> <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <value>file:C:/Data/conf/bigsoft.properties</value> </property> </bean> <!-- application beans --> <import resource="classpath:uk/co/bigsoft/myproj/config/application-config.xml"/> <!-- Data source Access --> <import resource="classpath:uk/co/bigsoft/myproj/config/database.xml"/> <!-- Real Dao --> <import resource="classpath:uk/co/bigsoft/myproj/config/dao.live.xml"/> <!-- Transaction support --> <import resource="classpath:uk/co/bigsoft/myproj/config/tx.xml"/> <!-- JMS support --> <import resource="classpath:uk/co/bigsoft/myproj/config/jms.xml"/> </beans>
PropertyPlaceholderConfigurer) is a configuration post-processor which substitutes variables given as part of the definition of other beans, and is really handy because this properties file can exist anywhere. The
application-config.xmlfile contains the business logic. This is the logic of the application that remains the same in the live and the development system, because it has been abstracted away from the infrastructure which follows. Each
importpulls in a configuration file containing beans which take care of an infrastructural aspect of the application while it runs in the live environment. In the case above I have split them up by technologies. Using
database.xmlas an example, I may have one file which uses MySQL and another that uses Oracle depending on my deployment strategy at that location. The second file pointer from
/WEB-INF/web.xmlpoints to the Servlet Dispatcher which is in charge of routing web traffic (or web services) to beans within my application. There is not much in here really. The file is the interface layer which utilizes the servlet container. The configuration file would change (somewhat) depending on what servlet container (or application server) you were using.
/WEB-INF/myproj-servlet-config.xmlis included for completeness
The main idea behind this layout is to promote the separation of concerns. The
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd" > <context:component-scan base-package="uk.co.bigsoft.myproj" /> <!-- Resolves logical view names to JSP views --> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/> <property name="prefix" value="/WEB-INF/views/"/> <property name="suffix" value=".jsp"/> </bean> <!-- Returns messages based on a resource bundle --> <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> <property name="basename" value="/WEB-INF/messages/validation" /> </bean> </beans>
application-config.xmlfile will almost certainly be split into several other files, to allow a more modular test approach. As you can see the components relating to the database, transaction model, JMS and other infrastructural aspects of the application are split away from the business logic. The business beans are not concerned with these behaviours, in fact the more decoupled from the rest of the system the better. Now that infrastructure is split from business the test environment can take full advantage of Spring’s Inversion of Control mechanism by faking up (or mocking) the infrastructural components and injecting them into the business beans. The mocks implement the same interfaces as the real beans and so test harnesses can be easily written.
No feedback yet
Form is loading...