Spring in Action
Spring in Action
Craig Walls
Spring Dallas User Group August 15, 2007 [email protected] These slides: http://www.habuma.com/spring/sia-sdug.pdf
About you
Java? .NET? Ruby/Rails?
Java 6? Java 5? Java 1.4? Java 1.3? 1.2 or older?
What is Spring?
Spring is
A POJO container? A lightweight framework? A platform? A catalyst for change?
Spring does
JSF Spring Batch Web Flow JMX Tapestry Caching JMS OSGi Ruby
EJB Portlet AJAX Transactions MVC AOP Security Web MVC Burlap RMI Dependency Hessian XML HttpInvoker Groovy Injection JDBC SOAP JDO Spring-WS E-mail Hibernate JPA iBATIS JNDI Rich Client JavaConfigStruts 2/ Scheduling .NET WebWork 2 JCA Struts Spring IDE
Spring does
Annotation-driven configuration
@Component, @Autowired JSR-250: @Resource, @PostConstructor, @PreDestroy
Autodetected components Requires JDK 1.4 or higher Named parameters added to SimpleJdbcTemplate ParameterizedBeanPropertyRowMapper for automatically mapping between columns and bean properties <context:load-time-weaver/> : Spring configured load time weaving Hibernate 2.1 support goes away JUnit 4.x support (in next milestone) Spring 2.5 ???
Dependency Injection
DI in a nutshell
Without DI, objects get their own dependencies
Directly through construction Through factories
Or perhaps
public class ValiantKnight { private Quest quest; public ValiantKnight() {}
Where does Quest come from?
public void setQuest(Quest quest) { this.quest = quest; How is it } Implemented? public void embarkOnQuest() { quest.embark(); } }
Aspect-Oriented Programming
AOP in a nutshell
Aspects decouple concerns from the objects that they apply to Common examples: Logging, caching, security, transactions Imagine a Minstrel class that chronicles a Knights exploits in song
Without AOP
public void embarkOnQuest() { minstrel.sing( "Fa la la, the knight is so brave!"); quest.embark(); minstrel.sing( "He did embark on a noble quest!"); }
With AOP
public void embarkOnQuest() { quest.embark(); }
Wheres the Minstrel?
Minstrel.java
public class Minstrel { public void singBefore() { System.out.println( "Fa la la, the knight is so brave!"); } public void singAfter() { System.out.println( "He did embark on a noble quest!"); } }
Using @AspectJ
@Aspect public class Minstrel { @Pointcut("execution(* *.embarkOnQuest(..))") public void embarkment() {} @Before("embarkment()") public void singBefore() { System.out.println( "Fa la la, the knight is so brave!"); } @After("embarkment()") public void singAfter() { System.out.println( "He did embark on a noble quest!"); } }
In Spring XML
<aop:aspectj-autoproxy />
Yepthats it
DI meets AOP
@Configurable enables injection into objects not managed by Spring
Domain objects, for example
Needs a load-time-weaver:
Spring 2.0: -javaagent:/path/to/aspect-weaver.jar Spring 2.1two options:
-javaagent:/path/to/spring-agent.jar <context:load-time-weaver />
Conventional JDBC
Connection conn = null; PreparedStatement stmt = null; ResultSet rs = null; try { conn = dataSource.getConnection(); stmt = conn.prepareStatement(select id, first_name, last_name from Employee where id=?"); stmt.setInt(1, id); rs.stmt.executeQuery(); Employee employee = null; if(rs.next()) { employee = new Employee(); employee.setId(rs.getInt(1)); employee.setFirstName(rs.getString(2)); employee.setLastName(rs.getString(3)); } return employee; } catch (SQLException e) {
Dj vu?
} finally { try { if(rs ! null) { rs.close(); } if(stmt != null) { stmt.close(); } if(conn != null) { conn.close(); } } catch (SQLException e) {} }
SQLException
The case of the ambiguous and useless checked exception
SQLException means that something went wrong with the databasebut what? The types of problems that SQLException represent are usually not runtimeaddressable.
What can you do in a catch block to handle a column not found error?
Springs DataAccessException
CannotAcquireLockException CannotSerializeTransactionException CleanupFailureDataAccessException ConcurrencyFailureException DataAccessException DataAccessResourceFailureException DataIntegrityViolationException DataRetrievalFailureException DeadlockLoserDataAccesException EmptyResultDataAccessException IncorrectResultSizeDataAccessException IncorrectUpdateSemanticsDataAccessException InvalidDataAccessApiUsageException InvalidDataAccessResourceUsageException OptimisticLockingFailureException PermissionDeniedDataAccessException PessimisticLockingFailureException TypeMismatchDataAccessException UncategorizedDataAccessException
JDBC: Spring-style
List matches = jdbcTemplate.query( "select id, first_name, last_name from Employee" + " where id=?", new Object[] {Long.valueOf(id)}, new RowMapper() { public Object mapRow(ResultSet rs, int rowNum) throws SQLException, DataAccessException { Employee employee = new Employee(); employee.setId(rs.getInt(1)); Notice no awkward employee.setFirstName(rs.getString(2)); try/catch block employee.setLastName(rs.getString(3)); return employee; } }); return matches.size() > 0 ? (Employee) matches.get(0) : null;
JDBC Template
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" > <property name="driverClassName value="org.hsqldb.jdbcDriver" /> <property name="url" value="jdbc:hsqldb:hsql://localhost/employee/employee" /> <property name="username" value="sa" /> <property name="password" value="" /> </bean> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" > <property name="dataSource" ref="dataSource" /> </bean> <bean id="employeeDao" class="com.springinaction.JdbcEmployeeDao"> <property name="jdbcTemplate" ref="jdbcTemplate" /> </bean>
Declarative Transactions
Spring 2 declarative tx
<tx:advice id="txAdvice"> <tx:attributes> <tx:method name="add*" propagation="REQUIRED" /> <tx:method name="*" propagation="SUPPORTS" read-only="true"/> </tx:attributes> </tx:advice> <aop:config> <aop:advisor advice-ref="txAdvice" pointcut="execution(* *..EmployeeService.*(..))" /> </aop:config>
Spring MVC
Auto-mapping of controllers
ControllerClassNameHandlerMapping:
<bean id="urlMapping" class="org.springframework.web.servlet.mvc.support. ControllerClassNameHandlerMapping" />
What about???
Struts 2/WebWork 2? JSF? Tapestry? Wicket? Seam? Grails? The billions of other MVC frameworks
Q&A
http://www.springinaction.com [email protected]