Spring Framework

By Sandeep Desai (http://www.thedesai.net/)

 

Spring AOP sample

 

 

The Spring Sample shows how an Advice can be added. The springconfig2.xml file shows how to setup a before and after method advice without modifying any of the original Java code

 

What is Spring?

 

The goal of Spring Framework is

 

See Rod Johnson’s Introduction to Spring Article

Inversion of Control by Martin Fowler

 

 

Spring is a framework that aims to simplify J2EE development

 

You can use all of Spring's functionality in any J2EE server, and most of it also in non-managed environments. A central focus of Spring is to allow for reusable business and data access objects that are not tied to specific J2EE services. Such objects can be reused across J2EE environments (web or EJB), standalone applications, test environments, etc without any hassle.

 

Spring has a layered architecture; all its functionality builds on lower levels. So you can e.g. use the JavaBeans configuration management without using the MVC framework or AOP support. But if you use the web MVC framework or AOP support, you'll find they build on the configuration framework, so you can apply your knowledge about it immediately.

 

Spring uses a setter based dependancy injection pattern (Inversion of Control).

 


Spring supports

Spring runs 1500 tests
Bug fixes made by creating tests
Creating samples important part of development
Test coverage using www.cenqua.com/clover/index.html

Spring IDE for development

Spring Redistributable


Spring IoC
  Dependancy Injection (better approach)
  Dependancy lookup
  Configuration in text property files or XML file
     PropertiesBeanDefinitionReader,
XmlBeanDefinitionReader
  DefaultListableBeanFactory to create beans
  XmlBeanFactory
 
Dependancy injection
Constructor injection
Setter injection
Collection injection (Set, List, Map, Property (String
based))

 

Spring Books (approx 6 books available)

 

Spring AOP support is dynamic. AspectJ has compile time support AOP

 

Spring and Hibernate

Download Source Code

 

public class MainMuleSpringHibernate {

    public static void main(String[] args) {

        String[] paths = {"springconfig.xml"};

        ApplicationContext ctx = new ClassPathXmlApplicationContext(paths);

        CategoryListDAO cdao = (CategoryListDAO) ctx.getBean("myCategoryDAO");

        // fails as we have lazy fetch on category and we are outside of session

        Book book = cdao.getBookFails("Hibernate in Action");

        try {

           System.out.println(book.getCategory().getName());

        } catch (LazyInitializationException e) {

          System.out.println("Caught **** " + e.getMessage());

        }

        // works as we have eager (join) fetch on category

        book = cdao.getBook("Hibernate in Action");

        System.out.println(book.getCategory().getName()); // will work

       

        Category c = cdao.getCategory("Java");

        if (c != null)

           cdao.createBook("Thinking in Java", c, 21, 33.27F);

    }

}

 

DAO Example

 

public class CategoryListDAO extends HibernateDaoSupport {

    public CategoryListDAO() {}

   

    public Category getCategory(String categoryName) {   

       List<Category> categories = getHibernateTemplate().find("from Category c where c.name = ?", categoryName);

       if (categories.size() > 0)

          return categories.get(0);

       return null;

    }

   

    public void createBook(String title, Category category, int inventory, float price) {

        Book book = new Book(title, category, inventory, price);

        getHibernateTemplate().save(book);

    }

 

    /**

     * Caller will fail when printing book.getCategory().getName();

     *    with LazyInitializationException as we did not fetch Category information

     * @param title

     * @return

     */

    public Book getBookFails(String title) {

        return (Book) getHibernateTemplate().execute(new HibernateCallback() {

              public Object doInHibernate(Session session)

                      throws HibernateException, SQLException {

                  Criteria criteria = session.createCriteria(Book.class);

                  criteria.add(Expression.eq("title", "Hibernate in Action"));

                  return criteria.uniqueResult();

              }

          });       

    }

   

    public Book getBook(final String title) {

        return (Book) getHibernateTemplate().execute(new HibernateCallback() {

              public Object doInHibernate(Session session)

                      throws HibernateException, SQLException {

                  Criteria criteria = session.createCriteria(Book.class);

                  criteria.add(Expression.eq("title", "Hibernate in Action"));

                  // Fetch everything in one query instead of 2

                  criteria.setFetchMode("category", FetchMode.JOIN); // EAGER Fetch

                  Book b = (Book)criteria.uniqueResult();

                  //System.out.println(b);

                  return b;

              }

          });

    }   

}

 

SpringConfig file example

 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
    "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
    <bean id="dataSource"
          class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName">
            <value>oracle.jdbc.driver.OracleDriver</value>
        </property>
        <property name="url">
            <value>jdbc:oracle:thin:@localhost:1521:orcl</value>
        </property>
        <property name="username">
            <value>scott</value>
        </property>
        <property name="password">
            <value>tiger</value>
        </property>
    </bean>
    <!-- Hibernate SessionFactory -->
    <bean id="sessionFactory"
          class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource">
            <ref local="dataSource"/>
        </property>
        <property name="mappingResources">
            <list>
                <value>net/thedesai/mule/model/Book.hbm.xml</value>
                <value>net/thedesai/mule/model/Category.hbm.xml</value>
                <value>net/thedesai/mule/model/Promotion.hbm.xml</value>
                <value>net/thedesai/mule/model/Customer.hbm.xml</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.Oracle9Dialect</prop>
                <prop key="hibernate.show_sql">true</prop>
            </props>
        </property>
    </bean>
    <!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) -->
    <bean id="transactionManager"
          class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory">
            <ref local="sessionFactory"/>
        </property>
    </bean>
    <!-- Tell Spring to setup a proxy around the DAO and do a transaction commit
         after methods listed in transactionAttributes
    -->
    <bean id="myCategoryDAOProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
        <property name="transactionManager" ref="transactionManager"/>
        <property name="target" ref="myCategoryDAO"/>
        <property name="transactionAttributes">
           <props>
               <!-- intercept createBook() call and start transaction if not already started
                    do a commit after method over
               -->
             <prop key="createBook*">PROPAGATION_REQUIRED</prop>
           </props>
        </property>
    </bean>
    <bean id="myCategoryDAO" class="net.thedesai.mule.dao.CategoryListDAO">
        <property name="sessionFactory">
            <ref local="sessionFactory"/>
        </property>
    </bean>
</beans>
 

 

 

Spring MVC Advantages

 

 

 

First, a level-set for those who don't know: Spring MVC controllers are roughly the equivalent of Struts actions. (Spring MVC's BaseCommandController is the closest approximation of a Struts Action.) Also, where Struts have ActionForms, Spring has "commands". And, instead of ActionForward, Spring has ModelAndView.

Advantage: Spring has a rich selection of Controller implementations ranging from the simplest (the Controller interface) to the very powerful (AbstractWizardFormController) and everything in between. You get to choose the controller implementation that best suits your needs. In Struts, you only have the Action class...if you need anything simpler, you are out of luck...if you need something more powerful, you have to subclass Action and implement it yourself.

Advantage: Spring's Controllers are much easier to test than Struts Actions. Spring's commands are anything that extends java.lang.Object (thus easy to mock). Struts form beans are classes that extend ActionForm (a bit harder to mock).

Disadvantage: The only disadvantage of Spring MVC over Struts is that because Spring MVC has a very rich selection of controllers, it may be harder to understand and know which controller to use. In fact, for a Spring newbie, the list of controller options can be overwhelming. But, if you take a look at Figure 8.4 in "Spring in Action", you'll see that Spring's Controller interface is much simpler than Struts' Action and that the other implementations progressively build upon that.

 

 

Links