Sunday, February 12, 2012

Spring 3.1 Framework - Spring 3.1 Java Configuration of a Spring MVC Application

Disclaimer:
All the software applications that appear below represent trademarks and they are the property of their respective owners.
Use and implement my notes in this article at your own risk.

The following topics are discussed:
1. Goals of Spring JavaConfig;
2. Spring Librairies Update
3. Overview of Spring JavaConfig;
4. Sample of AppConfig.java;
5. Sample of a Spring business service.
6. Sample of MvcConfig.java;
7. Sample of a Spring controller.
8. Considerations


(view of Spring app in action)

1. Goals of Spring JavaConfig
The main goal of Spring JavaConfig is to eliminate the XML code used to configure all the Spring components and to keep all the configuration in 2 main JavaConfig classes, namely, for example, AppConfig.java and MvcConfig.java.
This means practically passing all the configuration from XML to Java classes.

Note: this post is based on the previous one, namely "Spring 3.0 Java Configuration" which you should read before this one; next, we'll try to show that almost all the JavaConfig problems found at Spring 3.0 were solved at Spring Framework 3.1 release.

2. Spring Librairies Update
If you followed the Genereal Considerations, at the section "4. Assembly librairies" we used some Spring Framework 3.0.5 libraries. Now, these libs should be replaced with Spring Framework 3.1.0 libs.

So, in your app classpath, replace these libs:
<<
spring-aop-3.0.5.RELEASE.jar
spring-asm-3.0.5.RELEASE.jar
spring-beans-3.0.5.RELEASE.jar
spring-context-3.0.5.RELEASE.jar
spring-core-3.0.5.RELEASE.jar
spring-expression-3.0.5.RELEASE.jar
spring-javaconfig-1.0.0.m3.jar
spring-jdbc-3.0.5.RELEASE.jar
spring-orm-3.0.5.RELEASE.jar
spring-tx-3.0.5.RELEASE.jar
spring-web-3.0.5.RELEASE.jar
spring-webmvc-3.0.5.RELEASE.jar

>>
, with these ones:
<<
org.springframework.asm-3.1.0.RELEASE.jar
org.springframework.beans-3.1.0.RELEASE.jar
org.springframework.context-3.1.0.RELEASE
org.springframework.core-3.1.0.RELEASE.jar
org.springframework.expression-3.1.0.RELE
org.springframework.jdbc-3.1.0.RELEASE.jar
org.springframework.orm-3.1.0.RELEASE.jar
org.springframework.transaction-3.1.0.RELEASE.jar
org.springframework.web-3.1.0.RELEASE.jar
org.springframework.web.servlet-3.1.0.RELEASE.jar

>>

3. Overview of Spring JavaConfig

As we said before at Spring 3.0 JavaConfig, there are used special annotations in JavaConfig: @Configuration, @Import, @ImportResource, @Bean, aso.
For the Spring 3.1 JavaConfig, we'll use another annotations: @ComponentScan and @EnableTransactionManagement.
The @ComponentScan annotation intends to solve the problems of scanning packages for Spring components, in order for us not to define them in AppConfig.java and MvcConfig.java.
The @EnableTransactionManagement annotation will tell Spring to use driven annotated transactions or, more exactly, to detect the @Transactional annotation that we mapped in a Spring business component; The @EnableTransactionManagement annotation is equivalent to XML tag declaration: <tx:annotation-driven />, so after we use @EnableTransactionManagement we'll not need anymore the app-config.xml file that was imported in AppConfig.java (see Spring 3.0 JavaConfig).



4. Sample of AppConfig.java;
<<
package blog.configuration;

import java.util.Properties;

import javax.sql.DataSource;

import org.apache.commons.dbcp.BasicDataSource;
import org.hibernate.SessionFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.orm.hibernate3.HibernateTransactionManager;
import org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@Configuration
@ComponentScan("blog.services")
@EnableTransactionManagement

public class AppConfig {
   
    @Bean(name="dataSource")
    public DataSource dataSource() {
        BasicDataSource ds = new BasicDataSource();
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUsername("root");
        ds.setPassword("");
        ds.setUrl("jdbc:mysql://127.0.0.1:3306/blog");
        return ds;
    }

    @Bean(name="sessionFactory")
    public SessionFactory sessionFactory() {
        AnnotationSessionFactoryBean factoryBean = null;
        try {
            factoryBean = new AnnotationSessionFactoryBean();
            Properties pp = new Properties();
            pp.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5InnoDBDialect");
            pp.setProperty("hibernate.max_fetch_depth", "3");
            pp.setProperty("hibernate.show_sql", "false");
   
            factoryBean.setDataSource(dataSource());
            factoryBean.setPackagesToScan(new String[] {"blog.dao.*"});
            factoryBean.setHibernateProperties(pp);
            factoryBean.afterPropertiesSet();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return factoryBean.getObject();
    }
   
    @Bean(name="transactionManager")
    public HibernateTransactionManager transactionManager() {
        return new HibernateTransactionManager(sessionFactory());
    }
   
}

>>

Note: we observe in this file all the Java bean objects (Spring business components) that we defined in AppConfig.java at Spring 3.0 JavaConfig dissapeared. Also notice the presence of @ComponentScan and @EnableTransactionManagement annotations.

5. Sample of a Spring business service.
We will pass here the Java code used to create the Zone Spring service (namely ZoneDaoImpl), as an implementation of a user created ineterface (namely ZoneDao):
<<
package blog.services;

import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import blog.dao.ZoneDao;
import blog.dao.entities.Zone;

@Service
public class ZoneDaoImpl implements ZoneDao {

    private SessionFactory sessionFactory;

    @Autowired
    public ZoneDaoImpl(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    @Transactional(readOnly = true)
    @SuppressWarnings("unchecked")
    public List<Zone> getZones() {
        return (List<Zone>) getCurrentSession().createQuery("from Zone").list();
    }

    @Transactional(readOnly = true)
    public Zone getZoneByCod(String cod) {
        return (Zone) getCurrentSession().createQuery("from Zone z where z.cod=?").setParameter(0, (String) cod).uniqueResult();
    }

    @Transactional(readOnly = true)
    public Zone getZoneByName(String name) {
        return (Zone) getCurrentSession().createQuery("from Zone z where z.name=?").setParameter(0, (String) name).uniqueResult();
    }

    protected Session getCurrentSession() {
        return sessionFactory.getCurrentSession();
    }
}

>>
Note: as we used @ComponentScan in AppConfig.java, we need to use the @Service and @Autowired in ZoneDao Spring service.

6. Sample of MvcConfig.java;
<<
package blog.configuration;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

@Configuration
@ComponentScan("blog.controllers")

public class MvcConfig {

    @Bean
    InternalResourceViewResolver irResolver() {
        InternalResourceViewResolver ir = new InternalResourceViewResolver();
        ir.setPrefix("/views/");
        ir.setSuffix(".jsp");
        return ir;
    }

}

>>

Note: we observe in this file all the Java bean objects (Spring controllers) that we defined in MvcConfig.java at Spring 3.0 JavaConfig dissapeared. Also notice the presence of @ComponentScan.
Note: Because we replaced OpenSessionInViewInterceptor with OpenSessionInViewFilter and moved it in web.xml, we do not need anymore the mvc-config.xml file.

7. Sample of a Spring controller.
We will pass here the code used to create the Zone controller (namely ZoneController):
<<
package blog.controllers;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import blog.dao.ZoneDao;

@Controller
public class ZoneController {
   
    private ZoneDao zoneDao;
   
    @Autowired
    public ZoneController(ZoneDao zoneDao) {
        this.zoneDao = zoneDao;
    }
   
    @RequestMapping("/zoneList")
    public String zoneList(Model model) {
        model.addAttribute("zones", zoneDao.getZones());
        return "zoneList";
    }

}

>>
Note: as we used @ComponentScan in MvcConfig.java, we need to use the @Controller and @Autowired in ZoneController.

8. Considerations
The Spring JavaConfig may be useful as:
- we may keep all the configuration in 2 Java classes;
- no XML code for XML haters;

However, when used Spring 3.1 JavaConfig, I still haven't found a way to map the OpenSessionInViewInterceptor at the level of MvcConfig.java; a starting point could be to inherit the WebMvcConfigurerAdapter class in MvcConfig.java and to override the addInterceptors() method

Spring 3.0 Framework - Spring Java Configuration of a Spring MVC Application

Disclaimer:
All the software applications that appear below represent trademarks and they are the property of their respective owners.
Use and implement my notes in this article at your own risk.

The following topics are discussed:
1. Goals of Spring JavaConfig;
2. Updates in web.xml
3. Overview of Spring JavaConfig;
4. Sample of AppConfig.java;
5. Sample of a Spring business service.
6. Sample of MvcConfig.java;
7. Sample of a Spring controller.
8. Considerations


(view of Spring app in action)

1. Goals of Spring JavaConfig
The main goal of Spring JavaConfig is to eliminate the XML code used to configure all the Spring components and to keep all the configuration in 2 main JavaConfig classes, namely, for example, AppConfig.java and MvcConfig.java.
This means practically passing all the configuration from XML to Java classes.

However, the Spring 3.0 comes with a limited version of JavaConfig, that allows that only some Spring objects to be configured in Java classes. As we saw in XML configuration, there are many Spring namespaces that defines XML tags like: context, beans, tx, mvc, aop, aso. Practically, in Spring 3.0, only the "bean" XML tag can be mapped in Java classes. The rest of the XML tags that cannot be mapped to Java classes will remain in XML files and will be imported (we'll see later how is done).
Another problem is the component scanning of packages for Spring components, which is not suppoerted by Spring 3.0 JavaConfig.

Note: almost all the JavaConfig problems were solved at Spring Framework 3.1 release.

2 Updates in web.xml.
In order to use the JavaConfig, the following web.xml should be replaced:
<<
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/app-config.xml</param-value>
  </context-param>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>/WEB-INF/mvc-config.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>

>>
, with:
<<
    <context-param>
          <param-name>contextClass</param-name>
          <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
    </context-param>
    <context-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>blog.configuration.AppConfig</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextClass</param-name>
            <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
        </init-param>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>blog.configuration.MvcConfig</param-value>
        </init-param>
    <load-on-startup>1</load-on-startup>
    </servlet>

>>
Note: Practically, we told Spring to use JavaConfig classes (AppConfig and MvcConfig) as "contextClass" instead of using app-config.xml and mvc-config.xml.

Also, because the Spring 3.0 JavaConfig doesn't know about <mvc:interceptors /> tag in mvc-config.xml, we may replace the OpenSessionInViewInterceptor with OpenSessionInViewFilter.
So, we may add this in web.xml:
<<
      <filter>
        <filter-name>hibernateFilter</filter-name>
        <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
        <init-param>    
             <param-name>singleSession</param-name>      
             <param-value>true</param-value>  
        </init-param> 
        <init-param>
            <param-name>sessionFactoryBeanName</param-name>
            <param-value>sessionFactory</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>hibernateFilter</filter-name>
        <url-pattern>/web/*</url-pattern>
    </filter-mapping> 

>>
Note: in this way we assured that we can map all the JavaConfig XML objects from mvc-config.xml (as the other XML tags were "bean").

3. Overview of Spring JavaConfig
A Spring JavaConfig uses a special Spring annotation to mark the Java classes used for Spring Configuration.
This annotation is @Configuration. Any Java class annotated with @Configuration will become a Spring configuration class (JavaConfig class).
Like in the case of XML Configuration where the XML files could be splitted in many small XMLs and then imported in a final one (let's say app-config.xml), the JavaConfig classes can also be imported. This may be done by using @Import annotation.
Because of the limited capabilities of JavaConfig in Spring 3.0 and also to keep the backward compatibility, another annotation was necessaary to be defined: @ImportResource. @ImportResource is capable of importing an XML configuration file (like app-config.xml) in the respective JavaConfig class. This annotation is also necessary for us, because there is no way in Spring 3.0 to map in a JavaConfig class the XML tag <tx:annotation-driven /> or <context:component-scan />.
As we said, in JavaConfig only the "bean" XML tags may be defined. This is done by using a @Bean annotation.


4. Sample of AppConfig.java;
<<
package blog.configuration;

import java.util.Properties;

import javax.sql.DataSource;

import org.apache.commons.dbcp.BasicDataSource;
import org.hibernate.SessionFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
import org.springframework.orm.hibernate3.HibernateTransactionManager;
import org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean;

import blog.dao.CityDao;
import blog.dao.CountryDao;
import blog.dao.ZoneDao;
import blog.services.CityDaoImpl;
import blog.services.CountryDaoImpl;
import blog.services.ZoneDaoImpl;

@Configuration
@ImportResource({"classpath:config/app-config.xml"})
public class AppConfig {
   
    @Bean(name="dataSource")
    public DataSource dataSource() {
        BasicDataSource ds = new BasicDataSource();
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUsername("root");
        ds.setPassword("");
        ds.setUrl("jdbc:mysql://127.0.0.1:3306/blog");
        return ds;
    }

    @Bean(name="sessionFactory")
    public SessionFactory sessionFactory() {
        AnnotationSessionFactoryBean factoryBean = null;
        try {
            factoryBean = new AnnotationSessionFactoryBean();
            Properties pp = new Properties();
            pp.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5InnoDBDialect");
            pp.setProperty("hibernate.max_fetch_depth", "3");
            pp.setProperty("hibernate.show_sql", "false");
   
            factoryBean.setDataSource(dataSource());
            factoryBean.setPackagesToScan(new String[] {"blog.dao.*"});
            factoryBean.setHibernateProperties(pp);
            factoryBean.afterPropertiesSet();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return factoryBean.getObject();
    }
   
    @Bean(name="transactionManager")
    public HibernateTransactionManager transactionManager() {
        return new HibernateTransactionManager(sessionFactory());
    }

    @Bean(name="zoneDao")
    ZoneDao zoneDao() {
        return new ZoneDaoImpl(sessionFactory());
    }

    @Bean(name="countryDao")
    CountryDao countryDao() {
        return new CountryDaoImpl(sessionFactory());
    }

    @Bean(name="cityDao")
    CityDao cityDao() {
        return new CityDaoImpl(sessionFactory());
    }
   
}

>>

Note: we observe in this file all the XML "bean" tags that we defined in app-config.xml. Even if we used in web.xml an "AnnotationConfigWebApplicationContext" to tell Spring to use the AppConfig as configuration clas, we cannot use the component scanning and driven annotations, so we have to define entries for all the business components used (this is dued to the Spring 3.0 JavaConfig limitations).

Also, because in AppConfig.java we cannot include the "<tx:annotation-driven />" XML tag, we imported the app-config.xml file from "classpath:config/app-config.xml", which looks like:
<<
<?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:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
                            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                            http://www.springframework.org/schema/tx
                            http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

    <tx:annotation-driven transaction-manager="transactionManager" />

</beans>

>>

5. Sample of a Spring business service.
We will pass here the Java code used to create the Zone Spring service (namely ZoneDaoImpl), as an implementation of a user created ineterface (namely ZoneDao):
<<
package blog.services;

import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.transaction.annotation.Transactional;

import blog.dao.ZoneDao;
import blog.dao.entities.Zone;

public class ZoneDaoImpl implements ZoneDao {

    private SessionFactory sessionFactory;

    public ZoneDaoImpl(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    @Transactional(readOnly = true)
    @SuppressWarnings("unchecked")
    public List<Zone> getZones() {
        return (List<Zone>) getCurrentSession().createQuery("from Zone").list();
    }

    @Transactional(readOnly = true)
    public Zone getZoneByCod(String cod) {
        return (Zone) getCurrentSession().createQuery("from Zone z where z.cod=?").setParameter(0, (String) cod).uniqueResult();
    }

    @Transactional(readOnly = true)
    public Zone getZoneByName(String name) {
        return (Zone) getCurrentSession().createQuery("from Zone z where z.name=?").setParameter(0, (String) name).uniqueResult();
    }

    protected Session getCurrentSession() {
        return sessionFactory.getCurrentSession();
    }
}

>>
Note: we observe here that @Service and @Autowired are not used, as ZoneDao Spring service was defined in AppConfig.java.

6. Sample of MvcConfig.java;
<<
package blog.configuration;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

import blog.controllers.CityController;
import blog.controllers.CountryController;
import blog.controllers.ZoneController;
import blog.dao.CityDao;
import blog.dao.CountryDao;
import blog.dao.ZoneDao;

@Configuration
public class MvcConfig {

    @Autowired
    private ZoneDao zoneDao;

    @Autowired
    private CountryDao countryDao;

    @Autowired
    private CityDao cityDao;

    @Bean
    InternalResourceViewResolver irResolver() {
        InternalResourceViewResolver ir = new InternalResourceViewResolver();
        ir.setPrefix("/views/");
        ir.setSuffix(".jsp");
        return ir;
    }

    @Bean(name="/zoneList")
    ZoneController zoneController() {
        return new ZoneController(zoneDao);
    }

    @Bean(name="/countryList")
    CountryController countryController() {
        return new CountryController(countryDao);
    }

    @Bean(name="/cityList")
    CityController cityController() {
        return new CityController(cityDao);
    }
}

>>

Note: we observe in this file all the XML "bean" tags that we defined in mvc-config.xml. Even if we used in web.xml an "AnnotationConfigWebApplicationContext" to tell Spring to use the MvcConfig as configuration clas, we cannot use the component scanning and driven annotations, so we have to define entries for all the business components used (this is dued to the Spring 3.0 JavaConfig limitations).
Note: Because we replaced OpenSessionInViewInterceptor with OpenSessionInViewFilter and moved it in web.xml, we do not need anymore the mvc-config.xml file.

7. Sample of a Spring controller.
We will pass here the code used to create the Zone controller (namely ZoneController):
<<
package blog.controllers;

import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import blog.dao.ZoneDao;

public class ZoneController {
   
    private ZoneDao zoneDao;
   
    public ZoneController(ZoneDao zoneDao) {
        this.zoneDao = zoneDao;
    }
   
    @RequestMapping("/zoneList")
    public String zoneList(Model model) {
        model.addAttribute("zones", zoneDao.getZones());
        return "zoneList";
    }

}

>>
Note: we observe here that @Controller and @Autowired are not used, as ZoneController was defined in MvcConfig.java.

8. Considerations
The Spring JavaConfig may be useful as:
- we may keep all the configuration in 2 Java classes;
- no XML code for XML haters;

However, the Spring 3.0 does not provide full support for JavaConfig, so it's better to use Spring 3.1 if JavaConfig is really wanted.
Also, for the guys that likes to open a WAR archive and to look inside to see the app behaviour, they may have a surprise to see a black-box.
You may find here a Spring 3.1 Java Configuration to which the current Spring 3.0 Java Configuration serves as a basis.

Spring 3.0 Framework - Spring Annotation Configuration of a Spring MVC Application

Disclaimer:
All the software applications that appear below represent trademarks and they are the property of their respective owners.
Use and implement my notes in this article at your own risk.

The following topics are discussed:
1. Goals of Spring Annotation Configuration;
2. Overview of Spring Annotation Configuration;
3. Sample of app-config;
4. Sample of a Spring business service.
5. Sample of mvc-config.xml;
6. Sample of a Spring controller.
7. Considerations



(view of Spring app in action)


1. Goals of Spring Annotation Configuration
The main goal of Spring Annotation Configuration is to reduce the quantity of XML code used to configure all the Spring components.
This doesn't necessary mean that all the XML will disappear, as we still have to tell Spring to use annotations and in Spring 3.0 this can be done only in an XML file.
The Hibernate entities will also be configured to use annotations, as it is probably the best practice to keep under observation the Hibernate Configuration under a Spring MVC application.

2. Overview of Spring Annotation Configuration

A Spring Annotation Configuration uses Spring annotations to mark the Java classes used for different purposes in an MVC Spring app. The main annotations are: @Component, @Service, @Controller, @Transactional and @Autowired.
@Component is the parent annotation for all the Spring component annotations; for example, it is parent for @Service and @Controller. @Component may be used to mark user objects as beans or validators. @Component may be used to user define other type of component annotations.
@Service is an extended @Component annotation used to mark the Spring business services.
@Controller is an extended @Component annotation used to mark the Spring controllers.
@Transactional is an annotation that specifies that a Java method from a Spring service should be executed as a transaction.
@Autowired annotation is used in a new Spring component and tells Spring to search for other existing Spring components that are marked with @Component (or @Service, @Controller) and to use these existing components in the new created one.

As we said at the General Considerations, a Spring configuration is splitted in 2 sections:
a. app-config.xml file that configures the business components that is loaded by the Spring ContextLoaderListener;
So, in app-config we will have:
- a bean xml tag to define the datasource to bind to the MySQL database; we'll specify here: the JDBC driver for MySQL, the url of MySQL server, MySQL server username and passowrd;
- a bean xml tag to define the session factory that will create Hibernate sessions; we'll specify here: the datasource defined above, as a Hibernate session uses a database connecton; then, we will tell Hibernate which are the classes that maps the database tables; then we'll tell Hibernate what behaviour to have taking into account we use a MySQL database;
- a tx xml tag that will create the transaction manager; we'll specify here the session factory used to create Hibernate sessions that will be transacted;
- a bean xml tag (namely PersistenceExceptionTranslationPostProcessor) that will tell Spring to pass Hibernate type exceptions to Spring type exceptions;

Note: compared to XML configuration, we observe that the definitions for the business components have disappeared; also, the aop injection of transaction manager has disappeared because we used the @Transactional annotation.

b. mvc-config.xml file that configures the Controllers and Views Rendering that is loaded by Spring DispatcherServlet;
In mvc-config we'll have:
- a mvc xml tag that will define the list of Spring interceptors; in this list we'll define a bean xml tag, namely OpenSessionInViewInterceptor, that we'll lazily open the Hibernate sessions in order to be processed by Spring services;
- a bean xml tag to define the view resolver that will set the type of the view;

Note: compared to XML configuration, we observe that the definitions for the controllers have disappeared.
Note: both XML configuration files can extend other XML configuration files by importing them. For example we may have a file that defines the datasource, then another file that defines the session factory, then another file that defines the Spring services, then all 3 may be included in a single app-config.xml file.
Note: app-config.xml and mvc-config can have any other names, as long as they are specified in web.xml at their respective "contextConfigLocation" values.

3. Sample of app-config;
<<
<?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:jdbc="http://www.springframework.org/schema/jdbc"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
                            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                            http://www.springframework.org/schema/jdbc
                            http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
                            http://www.springframework.org/schema/tx
                            http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
                            http://www.springframework.org/schema/context
                            http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <context:annotation-config />
    <context:component-scan  base-package="blog.services" />
    <tx:annotation-driven transaction-manager="transactionManager" />
       
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://127.0.0.1:3306/blog" />
        <property name="username" value="root" />
        <property name="password" value="" />
    </bean>

    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="packagesToScan"> 
               <list> 
                <value>blog.dao.*</value> 
               </list> 
          </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
                <prop key="hibernate.max_fetch_depth">3</prop>
                <prop key="hibernate.show_sql">false</prop>
            </props>
        </property>
    </bean>

    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

    <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />

</beans>

>>

Note: we observe that we specified Spring to use "annotation-config" and to make "component-scan", more exactly to use @Autowired and @Component (in this case @Service).

4. Sample of a Spring business service.
We will pass here the Java code used to create the Zone Spring service (namely ZoneDaoImpl), as an implementation of a user created ineterface (namely ZoneDao):
<<
package blog.services;

import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import blog.dao.ZoneDao;
import blog.dao.entities.Zone;

@Service
public class ZoneDaoImpl implements ZoneDao {

    private SessionFactory sessionFactory;

    @Autowired
    public ZoneDaoImpl(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    @Transactional(readOnly = true)
    @SuppressWarnings("unchecked")
    public List<Zone> getZones() {
        return (List<Zone>) getCurrentSession().createQuery("from Zone").list();
    }

    @Transactional(readOnly = true)
    public Zone getZoneByCod(String cod) {
        return (Zone) getCurrentSession().createQuery("from Zone z where z.cod=?").setParameter(0, (String) cod).uniqueResult();
    }

    @Transactional(readOnly = true)
    public Zone getZoneByName(String name) {
        return (Zone) getCurrentSession().createQuery("from Zone z where z.name=?").setParameter(0, (String) name).uniqueResult();
    }

    protected Session getCurrentSession() {
        return sessionFactory.getCurrentSession();
    }
}

>>
Note: we observe here the use of @Service, @Autowired and @Transactional.

5. Sample of mvc-config.xml;
<<
<?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"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
                        http://www.springframework.org/schema/mvc     http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

    <context:component-scan base-package="blog.controllers" />   
    <mvc:annotation-driven />

    <mvc:interceptors>
        <bean class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor">
            <property name="sessionFactory" ref="sessionFactory" />
        </bean>
    </mvc:interceptors>

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/views/" />
        <property name="suffix" value=".jsp" />
    </bean>
   
</beans>

>>

Note: we observe that we specified Spring to use "annotation-config" and to make "component-scan", more exactly to use @Autowired and @Component (in this case, @Controller).

6. Sample of a Spring controller.
We will pass here the code used to create the Zone controller (namely ZoneController):
<<
package blog.controllers;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import blog.dao.ZoneDao;

@Controller
public class ZoneController {
   
    private ZoneDao zoneDao;
   
    @Autowired
    public ZoneController(ZoneDao zoneDao) {
        this.zoneDao = zoneDao;
    }
   
    @RequestMapping("/zoneList")
    public String zoneList(Model model) {
        model.addAttribute("zones", zoneDao.getZones());
        return "zoneList";
    }
}

>>
Note: we observe here the use of @Controller and @Autowired.

7. Considerations
The Spring Annotation Configuration may be useful as:
- we have a better programatic idea on how the components are linked together; for example we may see in the Java code which component is injected in which one;
- less XML code for XML haters;

However, the Spring Annotation Configuration is not well received by the organized users that like to have all the configuration in a single place; if a big Spring project is not well structured, then it is very hard to look for a class and to say which kind of Spring component it is. As a difference, the XML configuration keeps the configuration structured in the 2 XML configuration files.

So, in order to get the best of the 2 configurations discussed by now (XML and annotation configs), there was provided a third type of Spring Configuration, namely the JavaConfig.

Spring 3.0 Framework - Spring XML Configuration of a Spring MVC Application

Disclaimer:
All the software applications that appear below represent trademarks and they are the property of their respective owners.
Use and implement my notes in this article at your own risk.

The following topics are discussed:
1. Goals of Spring XML Configuration;
2. Overview of Spring XML Configuration;
3. Sample of app-config;
4. Sample of a Spring business service.
5. Sample of mvc-config.xml;
6. Sample of a Spring controller.
7. Considerations


(view of app in action)

1. Goals of Spring XML Configuration
The main goal of Spring XML Configuration is to have all the Spring components configured by using xml files.
This means that there will not be present any other type of Spring Configuration (like annotations or configuration via Java classes).
However, the Hibernate entities will be configured to use annotations, as it is probably the best practice to keep under observation the Hibernate Configuration under a Spring MVC application.

2. Overview of Spring XML Configuration
A Spring XML Configuration uses Spring namespaces to make available the sets of XML tags used in the configuration; the main Spring namespaces are: context, beans, jdbc, tx, aop, mvc, aso.
As we said at the General Considerations, a Spring configuration is splitted in 2 sections:
a. app-config.xml file that configures the business components that is loaded by the Spring ContextLoaderListener;
In app-config we will have:
- a bean xml tag to define the datasource to bind to the MySQL database; we'll specify here: the JDBC driver for MySQL, the url of MySQL server, MySQL server username and passowrd;
- a bean xml tag to define the session factory that will create Hibernate sessions; we'll specify here: the datasource defined above, as a Hibernate session uses a database connecton; then, we will tell Hibernate which are the classes that maps the database tables; then we'll tell Hibernate what behaviour to have taking into account we use a MySQL database;
- a tx xml tag that will create the transaction manager; we'll specify here the session factory used to create Hibernate sessions that will be transacted;
- an aop xml tag used to specify which are the business methods that will be transacted and how they will be transacted;
- a bean xml tag (namely PersistenceExceptionTranslationPostProcessor) that will tell Spring to pass Hibernate type exceptions to Spring type exceptions;
- an xml bean tag for each of the Spring services used to manipulate data on Hibernate entities; we'll specify here the session factory that will be injected in the respective Spring service;
b. mvc-config.xml file that configures the Controllers and Views Rendering that is loaded by Spring DispatcherServlet;
In mvc-config we'll have:
- a mvc xml object that will define the list of Spring interceptors; in this list we'll define a bean xml tag, namely OpenSessionInViewInterceptor, that we'll lazily open the Hibernate sessions in order to be processed by Spring services;
- a bean xml tag for each of the Spring controllers used to forward, retrieve and define the finally HTML rendered views; we'll specify here the Spring services that will be injected in the controller in order to get and set the data in the database;
- a bean xml tag to define the view resolver that will set the type of the view;

Note: both XML configuration files can extend other XML configuration files by importing them. For example we may have a file that defines the datasource, then another file that defines the session factory, then another file that defines the Spring services, then all 3 may be included in a single app-config.xml file.
Note: app-config.xml and mvc-config can have any other names, as long as they are specified in web.xml at their respective "contextConfigLocation" values.

3. Sample of app-config;
<<
<?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:jdbc="http://www.springframework.org/schema/jdbc"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
                            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                            http://www.springframework.org/schema/jdbc
                            http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
                            http://www.springframework.org/schema/tx
                            http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
                            http://www.springframework.org/schema/aop
                            http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
                            http://www.springframework.org/schema/context
                            http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://127.0.0.1:3306/blog" />
        <property name="username" value="root" />
        <property name="password" value="" />
    </bean>

    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="annotatedClasses">
            <list>
                <value>blog.dao.entities.Zone</value>
                <value>blog.dao.entities.Country</value>
                <value>blog.dao.entities.City</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
                <prop key="hibernate.max_fetch_depth">3</prop>
                <prop key="hibernate.show_sql">false</prop>
            </props>
        </property>
    </bean>

    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
       
    <tx:advice id="txAdviceTransactionManager" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="get*" read-only="true" />
            <tx:method name="*" read-only="true" propagation="SUPPORTS" isolation="DEFAULT" rollback-for="org.springframework.dao.DataAccessException" />           
        </tx:attributes>
    </tx:advice>

    <aop:config>
        <aop:pointcut id="transactionalOperation"
            expression="execution(* blog.services.*Impl.*(..))" />
        <aop:advisor advice-ref="txAdviceTransactionManager"
            pointcut-ref="transactionalOperation" />
    </aop:config>
   
    <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />

    <bean id="zoneDao" class="blog.services.ZoneDaoImpl">
        <constructor-arg ref="sessionFactory" />
    </bean>

    <bean id="countryDao" class="blog.services.CountryDaoImpl">
        <constructor-arg ref="sessionFactory" />
    </bean>

    <bean id="cityDao" class="blog.services.CityDaoImpl">
        <constructor-arg ref="sessionFactory" />
    </bean>
 </beans>

 >>

4. Sample of a Spring business service.

We will pass here the Java code used to create the Zone Spring service (namely ZoneDaoImpl), as an implementation of a user created ineterface (namely ZoneDao):
<<
package blog.services;

import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;

import blog.dao.ZoneDao;
import blog.dao.entities.Zone;

public class ZoneDaoImpl implements ZoneDao {

    private SessionFactory sessionFactory;

    public ZoneDaoImpl(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    @SuppressWarnings("unchecked")
    public List<Zone> getZones() {
        return (List<Zone>) getCurrentSession().createQuery("from Zone").list();
    }

    public Zone getZoneByCod(String cod) {
        return (Zone) getCurrentSession().createQuery("from Zone z where z.cod=?").setParameter(0, (String) cod).uniqueResult();
    }

    public Zone getZoneByName(String name) {
        return (Zone) getCurrentSession().createQuery("from Zone z where z.name=?").setParameter(0, (String) name).uniqueResult();
    }

    protected Session getCurrentSession() {
        return sessionFactory.getCurrentSession();
    }
}

>>


5. Sample of mvc-config.xml;
<<
<?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"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
                        http://www.springframework.org/schema/mvc     http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

    <mvc:interceptors>
        <bean class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor">
            <property name="sessionFactory" ref="sessionFactory"/>
        </bean>
    </mvc:interceptors>
   
    <bean name="/zoneList" class="blog.controllers.ZoneController">
        <constructor-arg ref="zoneDao"/>
    </bean>

    <bean name="/countryList" class="blog.controllers.CountryController">
        <constructor-arg ref="countryDao"/>
    </bean>

    <bean name="/cityList" class="blog.controllers.CityController">
        <constructor-arg ref="cityDao"/>
    </bean>

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/views/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
   
</beans>

>>

6. Sample of a Spring controller.

We will pass here the code used to create the Zone controller (namely ZoneController):
<<
package blog.controllers;

import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import blog.dao.ZoneDao;

public class ZoneController {
   
    private ZoneDao zoneDao;
   
    public ZoneController(ZoneDao zoneDao) {
        this.zoneDao = zoneDao;
    }
   
    @RequestMapping("/zoneList")
    public String zoneList(Model model) {
        model.addAttribute("zones", zoneDao.getZones());
        return "zoneList";
    }

}

>>

7. Considerations
The Spring XML Configuration may be useful as:
- we have all the Spring components configuration in only 2 files: app-config.xml and mvc-config.xml;
- XML files are text files, so they may be updated in a Java archive like a WAR for example;

However, the Spring XML Configuration is not well received by the users that like the programatic way of designing web applications or by those users that will say "ohhh, and do I have to write all this XML code ?!".
For these users, there were defined the next 2 kind of Spring MVC Configuration, namely the annotation and JavaConfig.

Spring 3.0 Framework - Ways to Configure a Spring MVC Application - General Considerations

Disclaimer:
All the software applications that appear below represent trademarks and they are the property of their respective owners.
Use and implement my notes in this article at your own risk.

The following topics are discussed:
1. General Considerations - overview of the subject;
2. Prerequisites - what you need to setup a Spring 3.0 MVC app;
3. Installation - installation of the tools needed (platforms, IDEs, aso);
4. Assembly librairies - setting up the used JEE librairies;
5. Configuration
6. MySQL database - database description;
7. Considerations;


1. General Considerations:
This section gives you some hints in how to setup a Spring 3.0 MVC application that uses Hibernate as persistence layer for MySQL database objects.
It is also used as a basis configuration for the next samples posted on this blog, namely:
"Spring 3.0 Framework - XML Configuration of a Spring MVC Application",
"Spring 3.0 Framework - Annotation Configuration of a Spring MVC Application",
"Spring 3.0 Framework - JavaConfig Configuration of a Spring MVC Application",
"Spring 3.1 Framework - JavaConfig Configuration of a Spring 3.1 MVC Application",

Note: My recommendation is to read in this order all the posts and to decide which one you will use in a Spring MVC project.
Note: While XML and Annotation Configurations are backward compatible with Spring Framework 2.5, a set of JavaConfig capabilities appeaqred firstly at Spring Framework 3.0 and the evolved at Spring Framework 3.1. All the configurations presented are forward compatible with just released Spring Framework 3.1 and future versions.

2. Prerequisites:
2.1 Operating System;
2.2. Java;
2.3. Development IDE;
2.4. Tomcat 7;
2.5. Spring 3.0.5 Framework;
2.6. Hibernate 3.6.0;
2.7. MySQL Connector;
2.8. Logging errors;

2.1. Operating System
I used WinXP SP3 for this sample, but you may use any OS on which you may install Java Virtual Machine.

2.2. Java
You will need to have installed Java JDK 1.6.0_x. Go download'em from Oracle website.

2.3. Development IDE
You may use:
- Netbeans;
- Eclipse with WTP;
- MyEclipse;
- SpringSource Tool Suite (STS).

In my case, I used SpringSource Tool Suite (STS) v. 2.8.1 which you may download and install for free, so google'it.

Generally speaking, you will need an IDE that supports JEE, not only JSE.

2.4. Tomcat 7
I used Apache Tomcat 7 as web container, but you may use any web servers that supports JEE deployments.

2.5. Spring 3.0.5 Framework
I used Spring v. 3.0.5
You need to download latest Spring Framework librairies, so google for'em;

2.6. Hibernate 3.6.0
Hibernate v. 3.6.0 was used, so, google it.

2.7. MySQL Connector
I used mysql-connector-java-5.1.14-bin.jar
Also, for Tomcat you may need: tomcat-jdbc.jar
I used MySQL 5, as I have it configured on the machine, but you may use any database support with the condition to configure the database connection driver.
Download MySQL 5 from Oracle, together with a visual database manager for MySQL; I used MySQL Administrator, but you may find others: Workbench, Heidi, Navicat, aso.

2.8. Logging errors
You will need to set a Java properties named log4j.properties, together with the following Java installed libraries:
log4j-1.2.16.jar
log4j-over-slf4j-1.6.1.jar
slf4j-api-1.5.8.jar
slf4j-jcl-1.5.8.jar

3. Installation
Once you downloaded all the above, you'll have to install:
- Java JDK; install to default specified location;
- Apache Tomcat 7 - install to default location; use the default specified port (8080) for tomcat HTTP web connector;
- Development IDE - install to specified location;
- MySQL - download to specified default location; use the default specified port (3306) for MySQL service database connectivity; also install the MySQL database manager (Administrator, Workbench, Heidi, aso) to default specified location;

Note: if installed, do not install again.

4. Assembly librairies
After you downloaded all the above, be sure you gathered on your disk and placed in a folder (let's say "lib") the following librairies.
Later, you should have these on the application library path:
  • antlr-2.7.6.jar
  • aopalliance-1.0.jar
  • asm-3.1.jar
  • cglib-2.2.jar // used only for JavaConfig
  • commons-collections-3.1.jar
  • commons-dbcp-1.3.jar
  • commons-logging-1.1.1.jar
  • commons-pool-1.5.4.jar
  • dom4j-1.6.1.jar
  • hibernate-annotations-3.5.3-Final.jar
  • hibernate-commons-annotations-3.2.0.Final.jar
  • hibernate-core-3.5.3-Final.jar
  • hibernate-jpa-2.0-api-1.0.0.Final.jar
  • javassist-3.9.0.GA.jar
  • jstl-1.2.jar
  • jta-1.1.jar
  • log4j-1.2.16.jar
  • log4j-over-slf4j-1.6.1.jar
  • mysql-connector-java-5.1.14-bin.jar
  • servlet-api-2.5.jar
  • slf4j-api-1.5.8.jar
  • slf4j-jcl-1.5.8.jar
  • spring-aop-3.0.5.RELEASE.jar
  • spring-asm-3.0.5.RELEASE.jar
  • spring-beans-3.0.5.RELEASE.jar
  • spring-context-3.0.5.RELEASE.jar
  • spring-core-3.0.5.RELEASE.jar
  • spring-expression-3.0.5.RELEASE.jar
  • spring-javaconfig-1.0.0.m3.jar
  • spring-jdbc-3.0.5.RELEASE.jar
  • spring-orm-3.0.5.RELEASE.jar
  • spring-tx-3.0.5.RELEASE.jar
  • spring-web-3.0.5.RELEASE.jar
  • spring-webmvc-3.0.5.RELEASE.jar

5. Configuration
Following Spring 3.0 MVC web app architecture, you will configure:
5.1. Spring 3.0 MVC app;
5.2. web.xml;
5.3. app-config.xml;
5.4. mvc-config.xml;
5.5. log4j.properties;

5.1. Spring 3.0 MVC physical structure
With your IDE development, create a new JEE project; name it "sprBlog".
Under "sprBlog" you should have:
- the "src" directory, in which will reside all your Java code;
- the "WEB-INF" directory that will store the web dependecy files: librairies (lib subfolder), web.xml, app-config.xml, aso;
- other web used subfolders: css, images, aso;

Note: in case of SpringSource Tool Suite (STS), all the functional web modules (WEB-INF plus css, images, aso are placed in an internal chosen folder named WebContent which constitutes the webroot of the web application; this folder ("WebContent") differs when using other IDEs.

Basically, the structure should look like in the image below taken from STS IDE:
Spring project app structure:


5.2. web.xml
This is the web app descriptor, located under "WEB-INF" application directory:
<<
<?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>sprBlog</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/app-config.xml</param-value>
  </context-param>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>/WEB-INF/mvc-config.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>/web/*</url-pattern>
  </servlet-mapping>
</web-app>

>>
In this file there is configured the listener and dispatcher for Spring Framework; the listener and the dispatcher are the main components that allows the definition of the Spring Framework in order to use it in a web application.

5.3. app-config.xml
This is the Spring configuration file, located unde "WEB-INF" directory. It is loaded by Spring ContextLoaderListener defined earlier in web.xml and defines the business components used later by Spring; more exactly, the business components represent the Model layer and the operations used on this Model to get and set data in the database; the Model is represented by Hibernate entities, while the database operations use Hibernate sessions that are manipulated by Spring services.

Here you should define at least:
a. a data source for the database you use (in our case is MySQL);
b. a session factory bean that uses a connection to your database in order to create a Hibernate working session; the session factory should know which are the Hibernate entities used to map the database tables and which is the database specific Hibernate behaviour;
c. a transaction manager that will be used in case of transactional Hibernate operations over the database;
d. the Spring business components (services) used to manipulate the Hibernate objects over the databae;

Note: This will be detailed in the next posts, as they refer to way of configuration of Spring 3.0 MVC application.

5.4. mvc-config.xml
This file is establish the MVC components used by Spring DispatcherServlet in order to manipulate the business components and to make them available to the web pages; more exactly, the dispatcher choses a Spring Controller that will render later a View with the help of a handler.

Here you should define at least:
a. the Spring Controllers used to render the Views;
b. one or more View resolvers that will define the type of the View that will be rendered; in Spring 3.0, the default rendered type is JSTL - this means that you may design Views as JSP files and control the data provided by Controllers with the help of JSTL;

Note: This will be detailed in the next posts, as they refer to way of configuration of Spring 3.0 MVC application.

5.5. log4j.properties
This is located under the classpath of application ("WEB-INF/classes" folder) and will configure log4j to log the app errors:
<<
log4j.rootLogger=ERROR, dest1
log4j.appender.dest1=org.apache.log4j.DailyRollingFileAppender
log4j.appender.dest1.File=${catalina.home}/logs/sprBlog.log
log4j.appender.dest1.DatePattern='.'yyyy-MM-dd
log4j.appender.dest1.layout=org.apache.log4j.PatternLayout
log4j.appender.dest1.layout.ConversionPattern=[%5p] [%t] %d{dd.MM.yyyy HH:mm:ss} %c (%F:%M:%L)%n%m%n%n

log4j.logger.blog=ERROR

log4j.logger.org.springframework=ERROR
log4j.logger.org.springframework.security=ERROR
log4j.logger.org.hibernate=ERROR
log4j.logger.org.apache=ERROR

>>
So, only ERROR type events will be logged to "${catalina.home}/logs/sprBlog.log".

Note. You may configure log4j to log the errors to your console by using org.apache.log4j.ConsoleAppender as log appender.

6. MySQL database
The database used in the following samples, namely "blog", contains 3 tables: zone, country, city. These tables are linked by foreign keys that will create a correspondence of the kind - zones include countries and countries include cities.
Use the following script to create the MySQL "blog" database from MySQL command line prompt:
<<
CREATE DATABASE IF NOT EXISTS blog;
USE blog;

DROP TABLE IF EXISTS `zone`;
CREATE TABLE `zone` (
  `cod` varchar(4) NOT NULL,
  `name` varchar(45) NOT NULL,
  PRIMARY KEY  (`cod`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `zone` (`cod`,`name`) VALUES
 ('AS','Asia'),
 ('EU','Europe'),
 ('NA','North America'),
 ('SA','South America');

DROP TABLE IF EXISTS `country`;
CREATE TABLE `country` (
  `cod` varchar(4) NOT NULL,
  `name` varchar(45) NOT NULL,
  `cod_zone` varchar(4) NOT NULL,
  PRIMARY KEY  (`cod`),
  KEY `FK_country_zone` (`cod_zone`),
  CONSTRAINT `FK_country_zone` FOREIGN KEY (`cod_zone`) REFERENCES `zone` (`cod`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `country` (`cod`,`name`,`cod_zone`) VALUES
 ('AG','Argentina','SA'),
 ('BR','Brasil','SA'),
 ('CA','Canada','NA'),
 ('CN','China','AS'),
 ('DE','Germany','EU'),
 ('FR','France','EU'),
 ('GR','Greece','EU'),
 ('RU','Russia','AS'),
 ('US','United States','NA');

DROP TABLE IF EXISTS `city`;
CREATE TABLE `city` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `cod_country` varchar(4) NOT NULL,
  `name` varchar(45) NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `FK_city_country` (`cod_country`),
  CONSTRAINT `FK_city_country` FOREIGN KEY (`cod_country`) REFERENCES `country` (`cod`)
) ENGINE=InnoDB AUTO_INCREMENT=25 DEFAULT CHARSET=latin1;

INSERT INTO `city` (`id`,`cod_country`,`name`) VALUES
 (1,'DE','Berlin'),
 (2,'DE','Dortmund'),
 (3,'DE','Munchen'),
 (4,'FR','Paris'),
 (5,'FR','Marseille'),
 (6,'FR','Bordeaux'),
 (7,'GR','Athens'),
 (8,'GR','Thesaloniki'),
 (9,'GR','Larissa'),
 (10,'US','Seattle'),
 (11,'US','New York'),
 (12,'US','Detroit'),
 (13,'US','Los Angeles'),
 (14,'CA','Toronto'),
 (15,'CA','Montreal'),
 (16,'CA','Vancouver'),
 (17,'BR','Janeiro'),
 (18,'BR','Brasil'),
 (19,'AG','Aires'),
 (20,'RU','Moscow'),
 (21,'RU','Stalingrad'),
 (22,'RU','Petersburg'),
 (23,'CN','Beijing'),
 (24,'CN','Nanjang');

>>

7. Considerations
Having all the above installed and configured, we may follow the next sections that describe the Spring 3.0 MVC application possible configurations.