The Spring Framework, - Software Summitsoftwaresummit.com/2005/speakers/RaibleSpringOverview.pdf ·...

76
The Spring Framework, Simplifying J2EE Matt Raible www.springlive.com Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC Matt Raible — The Spring Framework, Simplifying J2EE Page 1

Transcript of The Spring Framework, - Software Summitsoftwaresummit.com/2005/speakers/RaibleSpringOverview.pdf ·...

The Spring Framework,Simplifying J2EE

Matt Raiblewww.springlive.com

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 1

Introductions

Your experience with Spring?Your experience with J2EE?What do you hope to learn in this session?Open Source experience: Ant, XDoclet, Hibernate?Favorite IDE? Favorite OS?

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 2

Matt

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 3

Raible

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 4

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 5

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 6

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 7

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 8

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 9

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 10

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 11

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 12

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 13

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 14

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 15

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 16

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 17

Who is Matt Raible?Father, Husband, Open Source Practice Leader

Developing websites since 1994 - Developing J2EE webapps since 1999

Committer on several open source projects: AppFuse, Roller Weblogger, XDoclet, Struts Menu, Display Tag

J2EE 5.0 and JSF 1.2 Expert Group Member

Author: Spring Live (SourceBeat) and contributor to Pro JSP (Apress)

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 18

J2EE 5.0 and JSF 1.2 Expert Group Member

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 19

Spring Mission Statement

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 20

What is Spring?

A J2EE Framework designed to make building applications easierProvides a means to manage your business objects and their dependenciesInversion of Control allows classes to be loosely coupled and dependencies written in XMLÀ la carte framework that allows you to pick and choose features to use

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 21

Spring Modules

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 22

Sample Architecture

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 23

The BeanFactory

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 24

XML Context File<?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="propertyConfigurer"

class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">

<property name="location" value="classpath:jdbc.properties"/>

</bean>

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">

<property name="driverClassName" value="${jdbc.driverClassName}"/>

<property name="url" value="${jdbc.url}"/>

<property name="username" value="${jdbc.username}"/>

<property name="password" value="${jdbc.password}"/>

</bean>

</beans>

jdbc.driverClassName=com.mysql.jdbc.Driver

jdbc.url=jdbc:mysql://localhost/equinox

jdbc.username=root

jdbc.password=

jdbc.properties:

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 25

ClassPathXmlApplicationContext - load files from classpathFileSystemXmlApplicationContext - load from filesystem (relative or absolute paths)StaticXmlApplicationContext - allows programmatic registration of beansXmlWebApplicationContext - used by ContextLoaderListener to read paths from web.xml

Get that Context!

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 26

ClassPathXmlApplicationContext

ApplicationContext ctx = new ClassPathXmlApplicationContext("/WEB-INF/applicationContext.xml");

String paths[] = new String[] {"/WEB-INF/applicationContext-hibernate.xml",

"/WEB-INF/applicationContext.xml"};

ApplicationContext ctx = new ClassPathXmlApplicationContext(paths);

ApplicationContext ctx = new ClassPathXmlApplicationContext("/WEB-INF/applicationContext*.xml");

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 27

Dependency Injection

Hollywood Principle:“Don’t call me, I’ll call you.”

http://martinfowler.com/articles/injection.html

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 28

Dependency Injection

Lookup dependencies vs. Exposing dependencies

Easy to mock dependencies (i.e. in unit tests)

Spring supports constructor injection, setter injection and method injection

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 29

Example: Controller and DAOController has a setter or a constructor argument for the DAO

DAO is configured as a dependency of the Controller

Makes it easy to swap out implementations

Tests can verify operations succeed on the interface

<bean id="userController" class="org.appfuse.web.UserController"> <property name="userDAO" ref="userDAO"/> </bean> <bean id="userDAO" class="org.appfuse.dao.UserDAOHibernate"> <property name="sessionFactory" ref="sessionFactory"/> </bean>

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 30

Code before IoC

public class UserController implements Controller {

public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception { Connection conn = DatabaseUtils.getConnection(); UserDAO dao = DAOFactory.createUserDAO("hibernate", conn); List users = dao.getUsers();

DatabaseUtils.closeConnection(conn); return new ModelAndView("userList", "users", users); }}

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 31

Code after IoC

public class UserController implements Controller { private UserDAO dao = null;

public void setUserDAO(UserDAO userDAO) { this.dao = userDAO; }

public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception { List users = dao.getUsers(); return new ModelAndView("userList", "users", users); }}

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 32

Setter Injection

public class UserController implements Controller { private UserDAO dao = null;

public void setUserDAO(UserDAO userDAO) { this.dao = userDAO; }

public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception { List users = dao.getUsers(); return new ModelAndView("userList", "users", users); }}

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 33

Setter Injection

public class UserController implements Controller { private UserDAO dao = null;

public void setUserDAO(UserDAO userDAO) { this.dao = userDAO; }

<bean id="userController" class="org.appfuse.web.UserController"> <property name="userDAO" ref="userDAO"/></bean>

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 34

Constructor Injection

public class UserController implements Controller { private UserDAO dao = null;

public UserController(UserDAO userDAO) { this.dao = userDAO; }

public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception { List users = dao.getUsers(); return new ModelAndView("userList", "users", users); }}

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 35

Constructor Injection

public class UserController implements Controller { private UserDAO dao = null;

public UserController(UserDAO userDAO) { this.dao = userDAO; }

<bean id="userController" class="org.appfuse.web.UserController"> <constructor-arg index=”0” ref="userDAO"/></bean>

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 36

Spring vs. J2EE

It’s not really a comparison, Spring builds off J2EE and merely makes the APIs easierIt’s still using many of J2EE’s and Java’s underlying infrastructureEJB vs. Spring Managed POJOsClustering and Fail-over supported better by EJB

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 37

Spring simplifies EJBsAbstract classes in org.springframework.ejb.support override methods that you normally don’t implement

Expose EJBs as Spring beans with classes in org.springframework.ejb.access package

Configuring a JtaTransactionManager will allow Spring beans to participate in CMT

<bean id="simpleService" lazy-init="true"

class="org.springframework.ejb.access.SimpleRemoteStatelessSessionProxyFactoryBean">

<property name="jndiName" value="jndiName"/>

<property name="cacheHome" value="true"/>

<property name="businessInterface" value="org.appfuse.ejb.SimpleService"/>

</bean>

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 38

Testing Spring ApplicationsEasy to mock dependencies with EasyMock and jMock

Load context in tests and bind dependencies as you would in productionTIP: Use a static block or Spring classes in Spring Mock (org.springframework.test package)

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 39

Spring MocksStubs for Servlet and JNDI API

Spring’s org.springframework.test package has a number of base classes to simplify testingAbstractDependencyInjectionSpringContextTests - can do both setter or field-based dependency injection, cached context files

AbstractTransactionalDataSourceSpringContextTests - allows you to easily clear data from tables and rolls back any data entered into the database

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 40

AbstractTransactionalDataSourceSpringContextTests

public class UserManagerIntegrationTest extends AbstractTransactionalDataSourceSpringContextTests {

private UserManager userManager;

public void setUserManager(UserManager userManager) {

this.userManager = userManager;

}

protected String[] getConfigLocations() {

return new String[] {"classpath*:/WEB-INF/applicationContext*.xml"};

}

protected void onSetUpInTransaction() throws Exception {

deleteFromTables(new String[] {"app_user"});

}

public void testGetUsers() {

User kid1 = new User();

kid1.setFirstName("Abbie");

kid1.setLastName("Raible");

User kid2 = new User();

kid2.setFirstName("Jack");

kid2.setLastName("Raible");

userManager.saveUser(kid1);

userManager.saveUser(kid2);

assertEquals(2, userManager.getUsers().size());

}

}

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 41

Data Access Support

Meaningful ExceptionsNo more try/catch/finallyDaoSupport and Template classes for many frameworks

Hibernate, iBATIS, JDO, OJB and TopLink

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 42

Rich Exception Hierarchy

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 43

Data Access Examples

UserDAOTestHibernateiBATISSpring JDBCOJBJDO

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 44

Hibernatepublic class UserDAOHibernate extends HibernateDaoSupport implements UserDAO {

public List getUsers() { return getHibernateTemplate().find("from User"); }

public User getUser(Long id) { User user = (User) getHibernateTemplate().get(User.class, id); if (user == null) { throw new ObjectRetrievalFailureException(User.class, id); } return user; }

public void saveUser(User user) { getHibernateTemplate().saveOrUpdate(user); }

public void removeUser(Long id) { getHibernateTemplate().delete(getUser(id)); }}

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 45

iBATISpublic class UserDAOiBatis extends SqlMapClientDaoSupport implements UserDAO {

public List getUsers() { return getSqlMapClientTemplate().queryForList("getUsers", null); }

public User getUser(Long id) { User user = (User) getSqlMapClientTemplate().queryForObject("getUser", id);

if (user == null) { throw new ObjectRetrievalFailureException(User.class, id); }

return user; }

public void removeUser(Long id) { getSqlMapClientTemplate().update("deleteUser", id); }}

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 46

iBATIS SQL<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN" "http://www.ibatis.com/dtd/sql-map-2.dtd">

<sqlMap namespace="UserSQL"> <select id="getUser" parameterClass="java.lang.Long" resultClass="org.appfuse.model.User"> select id, first_name as firstName, last_name as lastName from app_user where id=#id#; </select> <select id="getUsers" resultClass="org.appfuse.model.User"> select id, first_name as firstName, last_name as lastName from app_user; </select> <delete id="deleteUser" parameterClass="java.lang.Long"> delete from app_user where id = #id#; </delete>

</sqlMap>

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 47

JDOpublic class UserDAOJdo extends JdoDaoSupport implements UserDAO { public List getUsers() { Collection users = getJdoTemplate().find(User.class); users = getPersistenceManager().detachCopyAll(users); return new ArrayList(users); }

public User getUser(Long id) { User user = (User) getJdoTemplate().getObjectById(User.class, id); if (user == null) { throw new ObjectRetrievalFailureException(User.class, id); } return (User) getPersistenceManager().detachCopy(user); }

public void saveUser(User user) { if (user.getId() == null) { getJdoTemplate().makePersistent(user); } else { getPersistenceManager().attachCopy(user, true); } }

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 48

OJBpublic class UserDAOOjb extends PersistenceBrokerDaoSupport implements UserDAO { public List getUsers() { return new ArrayList(getPersistenceBrokerTemplate(). getCollectionByQuery(new QueryByCriteria(User.class))); }

public User getUser(Long id) { Criteria criteria = new Criteria(); criteria.addEqualTo("id", id); User user = (User) getPersistenceBrokerTemplate() .getObjectByQuery(new QueryByCriteria(User.class, criteria)); if (user == null) { throw new ObjectRetrievalFailureException(User.class, id); }

return user; }

public void saveUser(User user) { getPersistenceBrokerTemplate().store(user); }

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 49

Spring JDBC

public class UserDAOJdbc extends JdbcDaoSupport implements UserDAO { public List getUsers() { return new UsersQuery(getDataSource()).execute(); } public User getUser(Long id) { List users = new UserQuery(getDataSource()).execute(new Object[]{id}); if (users.isEmpty()) { throw new ObjectRetrievalFailureException(User.class, id); } return (User) users.get(0); } public void removeUser(Long id) { getJdbcTemplate().update("DELETE FROM app_user WHERE id = ?", new Object[] {id}); }

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 50

Spring JDBC

public class UserDAOJdbc extends JdbcDaoSupport implements UserDAO { public List getUsers() { return new UsersQuery(getDataSource()).execute(); } public User getUser(Long id) { List users = new UserQuery(getDataSource()).execute(new Object[]{id}); if (users.isEmpty()) { throw new ObjectRetrievalFailureException(User.class, id); } return (User) users.get(0); } public void removeUser(Long id) { getJdbcTemplate().update("DELETE FROM app_user WHERE id = ?", new Object[] {id}); }

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 51

MappingSqlQuery // Query to get a single User

class UserQuery extends MappingSqlQuery {

public UserQuery(DataSource ds) {

super(ds, "SELECT * FROM app_user WHERE id = ?");

super.declareParameter(new SqlParameter("id", Types.INTEGER));

compile();

}

protected Object mapRow(ResultSet rs, int rowNum) throws SQLException {

User user = new User();

user.setId(new Long(rs.getLong("id")));

user.setFirstName(rs.getString("first_name"));

user.setLastName(rs.getString("last_name"));

return user;

}

}

// Query to get a list of User objects

class UsersQuery extends MappingSqlQuery {

public UsersQuery(DataSource ds) {

super(ds, "SELECT * FROM app_user");

compile();

}

protected Object mapRow(ResultSet rs, int rowNum) throws SQLException {

...

}

}

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 52

Spring MVC

Front-Controller Servlet: DispatcherServlet

Controllers loaded as beans from servlet’s XML context files

ContextLoaderListener loads other XML context files

Many different Controller options: Controller, SimpleFormController, Wizard

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 53

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 54

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 55

Pros:Lifecyle for overriding binding, validation, etc.Integrates with many view options seamlessly: JSP/JSTL, Tiles, Velocity, FreeMarker, Excel, XSL, PDFInversion of Control makes it easy to test

Cons:Configuration intensive - lots of XMLRequires writing lots of code in JSPsAlmost too flexible - no common parent Controller

Controller and JSP Examples

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 56

Spring Controllerpublic class UserController implements Controller {

private final Log log = LogFactory.getLog(UserController.class); private UserManager mgr = null;

public void setUserManager(UserManager userManager) {

this.mgr = userManager; }

public ModelAndView handleRequest(HttpServletRequest request,

HttpServletResponse response) throws Exception {

if (log.isDebugEnabled()) { log.debug("entering 'handleRequest' method...");

}

return new ModelAndView("userList", "users", mgr.getUsers()); }

}

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 57

Spring Controllerpublic class UserController implements Controller {

private final Log log = LogFactory.getLog(UserController.class); private UserManager mgr = null;

public void setUserManager(UserManager userManager) {

this.mgr = userManager; }

public ModelAndView handleRequest(HttpServletRequest request,

HttpServletResponse response) throws Exception {

if (log.isDebugEnabled()) { log.debug("entering 'handleRequest' method...");

}

return new ModelAndView("userList", "users", mgr.getUsers()); }

}

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 58

Display Tag<display:table name="users" class="list" requestURI="" id="userList" export="true">

<display:column property="id" sort="true" href="editUser.html" paramId="id" paramProperty="id" titleKey="user.id"/>

<display:column property="firstName" sort="true" titleKey="user.firstName"/> <display:column property="lastName" sort="true" titleKey="user.lastName"/>

<display:column titleKey="user.birthday" sort="true" sortProperty="birthday"> <fmt:formatDate value="${userList.birthday}" pattern="${datePattern}"/>

</display:column></display:table>

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 59

Spring: userForm.jsp

<form method="post" action="<c:url value="/editUser.html"/>"

onsubmit="return validateUser(this)" name="userForm"><spring:bind path="user.id">

<input type="hidden" name="id" value="${status.value}"/> </spring:bind>

<table class="detail"><tr>

<th><label for="firstName"> <fmt:message key="user.firstName"/>:</label></th>

<td> <spring:bind path="user.firstName">

<input type="text" name="${status.expression}" id="firstName" value="${status.value}"/>

<span class="fieldError">${status.errorMessage}</span> </spring:bind>

</td></tr>

<tr>

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 60

Spring: userForm.jsp

<form method="post" action="<c:url value="/editUser.html"/>"

onsubmit="return validateUser(this)" name="userForm"><spring:bind path="user.id">

<input type="hidden" name="id" value="${status.value}"/> </spring:bind>

<table class="detail"><tr>

<th><label for="firstName"> <fmt:message key="user.firstName"/>:</label></th>

<td> <spring:bind path="user.firstName">

<input type="text" name="${status.expression}" id="firstName" value="${status.value}"/>

<span class="fieldError">${status.errorMessage}</span> </spring:bind>

</td></tr>

<tr>

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 61

Spring Supports many Java MVC Frameworks

ContextLoaderListener loads beans into ServletContext - can retrieve with:WebApplicationContext ctx =

WebApplicationContextUtils.getWebApplicationContext(servletContext);

Struts has ContextLoaderPlugin and ActionSupport classesWebWork has SpringObjectFactory

Tapestry - override BaseEngine and stuff the context into the Global

JSF - DelegatingVariableResolver

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 62

Spring Web Flow<webflow id="userFlow" start-state="setupForm">

<action-state id="setupForm">

<action bean="userFormAction"/>

<transition on="success" to="display.nameForm"/>

</action-state>

<view-state id="display.nameForm" view="flow/name">

<transition on="submit" to="display.addressForm">

<action bean="userFormAction" method="bindAndValidate"/>

</transition>

<transition on="cancel" to="finish"/>

</view-state>

<view-state id="display.addressForm" view="flow/address">

<transition on="previous" to="display.nameForm">

<action bean="userFormAction" method="bindAndValidate"/>

</transition>

<transition on="submit" to="display.otherForm">

<action bean="userFormAction" method="bindAndValidate"/>

</transition>

<transition on="cancel" to="finish"/>

</view-state>

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 63

MVC Tips

Using IoC for setting Controller/Action dependencies makes it easy to mock themJSP 2.0 Tag files in JIRA - for syntax simplificationUse SiteMesh - simple yet powerfulAppFuse and Equinox have good integration examples

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 64

Transactions

Much easier to use than UserTransaction in J2EECMT-like capabilities with XML and transparent AOPSupports Commons Attributes and JDK 5 AnnotationsPluggable Transaction Managers, including JTA

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 65

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 66

Spring Example

public void saveUser(final User user) {

txTemplate.execute(new TransactionCallbackWithoutResult() { public void doInTransactionWithoutResult(TransactionStatus status) {

dao.saveUser(user); }

});}

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 67

Declarative Transactions<?xml version="1.0" encoding="UTF-8"?>

<?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="txProxyTemplate" abstract="true"

class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">

<property name="transactionManager" ref="transactionManager"/>

<property name="transactionAttributes">

<props>

<prop key="save*">PROPAGATION_REQUIRED</prop>

<prop key="remove*">PROPAGATION_REQUIRED</prop>

<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>

</props>

</property>

</bean>

<bean id="userManager" parent="txProxyTemplate">

<property name="target">

<bean class="org.appfuse.service.impl.UserManagerImpl">

<property name="userDAO" ref="userDAO"/>

</bean>

</property>

</bean>

</beans>

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 68

Spring AOP

What is AOP? “Aspect-Oriented Programming”

Handling the 20% of problems that Object-Oriented programming can’t solve

A way of removing code duplication between classes that aren’t in the same hierarchy

Applications have core concerns (functionality) and cross cutting concerns (aspects)

With Spring AOP, an interceptor is used to inspect method calls

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 69

Logging ExampleReplace log.debug(”...”) at beginning and end of method calls

In order to intercept a bean’s method, it must be configured as a proxied class

org.springframework.aop.interceptor.SimpleTraceInterceptor

Practical AOP Examples:

Transactions

Caching in your middle-tier

Performance Monitoring

Event Notification

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 70

SimpleTraceInterceptorAdd a “preInterceptors” property

Change log4j.xml to show log messages

<bean id="userManager" parent="txProxyTemplate">

<property name="target">

<bean class="org.appfuse.service.impl.UserManagerImpl">

<property name="userDAO" ref="userDAO"/>

</bean>

</property>

<property name="preInterceptors">

<list>

<ref bean="loggingInterceptor"/>

</list>

</property>

</bean>

<logger name="org.springframework.aop.interceptor">

<level value="DEBUG"/>

</logger>

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 71

Related Projects

Acegi Security for SpringSpring Rich Client ProjectSpring Web FlowSpring Web Services FrameworkTrailsAppFuse and Equinox

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 72

Remoting & Web ServicesRMI using RmiProxyFactoryBean and RmiServiceExporter

Spring’s HTTP Invoker: Java serialization over HTTP using HttpInvokerProxyFactoryBean and HttpInvokerServiceExporter

Hessian: lightweight binary HTTP-based protocol

Burlap: XML-based alternative to Hessian

JAX RPC: for Web Services

http://www.springframework.org/docs/reference/remoting.html

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 73

ToolsSpring IDE Plugin For Eclipse

http://springide.org

BeanDochttp://opensource.atlassian.com/confluence/spring/display/BDOC/Home

Gaijin Studiohttp://gaijin-studio.sf.net

Screenshots

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 74

Resources

Web: www.springframework.org and forum.springframework.orgPrint: Spring Live, Pro Spring, Spring in Action and Professional Spring DevelopmentExamples: AppFuse (appfuse.dev.java.net), Equinox (equinox.dev.java.net), JPetstoreTraining: Virtuas, Interface21

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 75

Please fill out the evals!

http://tinyurl.com/agczp

[email protected]

Colorado Software Summit: October 23 – 28, 2005 © Copyright 2005, Virtuas, LLC

Matt Raible — The Spring Framework, Simplifying J2EE Page 76