Download - Spring 2.5
The Spring FrameworkPaul Bakker
Goals
An introduction
Not pointing a winner
Outline
• History and overview
• Dependency Injection
• AOP
• Module deep dive
• Testing
History
Founded by Rod Johnson
First introduced in his book “J2EE Design & Development”
Modules
Why Dependency Injection?
H o w w o u l d y o u t e s t t h i s m e t h o d ?
publicdoublecalculateTotalPrice(){ProductServiceproductService=newProductService();Listproducts=productService.getProducts();
//iterateproductsandsumprices
returntotal;}
productService.getProducts()
Database
publicdoublecalculateTotalPrice(){ProductServiceproductService=newProductService();Listproducts=productService.getProducts();
//iterateproductsandsumprices
returntotal;}
publicvoidtestCalculateTotalPrice(){Calculatorcalc=newCalculator();assertEquals(150,calc.calculateTotalPrice());
}
Throws Exception...
publicCalculator(ProductServiceproductService){this.productService=productService;
}
publicdoublecalculateTotalPrice(){Listproducts=productService.getProducts();
//iterateproductsandsumprices
returntotal;}
publicvoidtestCalculateTotalPrice(){Calculatorcalc=newCalculator(newProductServiceMock());
assertEquals(150,calc.calculateTotalPrice());}
Program to interfaces
not to implementations
Inversion of Control
A container manages dependencies
ProductService Calculator
IoC Container
Configuring a container
ProductServicepService=newProductServiceImpl();Calculatercalc=newCalculator(pService);
//initotherinstances
This will be a lot of work however...
Configuration using XML
<beanid="productService"class="services.ProductServiceImpl"/>
<beanid="calculator"class="calc.Calculator"><constructor‐argindex="0"ref="productService"/></bean>
Spring version 1 way
Configuration using annotations
@Stateless(name="ProductEJB")publicclassProductBean{publicProductBean(){}}
JEE 5 way
@EJBShoppingBasketBeanshoppingBasket;
Spring annotations
• Spring can now be configured using annotations
• Use annotations for component declarations
• Use XML for container wide configuration
Annotation example
@ServicepublicclassSimpleMovieLister{privateMovieFindermovieFinder;@AutowiredpublicSimpleMovieLister(MovieFindermovieFinder){this.movieFinder=movieFinder;}}
AutoWiring
• Don’t explicitly wire dependencies
• Just declare beans
Autowiring qualifiers<beanclass="example.SimpleMovieCatalog"><qualifiervalue="main"/></bean>
<beanclass="example.SimpleMovieCatalog"><qualifiervalue="action"/></bean>
@Autowired@Qualifier("main")privateMovieCatalogmovieCatalog;
Aspect Oriented Programming
• Used internally by Spring;
• e.g. Transaction Management
• AspectJ integration for easy AOP on your Spring beans
2 minute AOP intro
public void myMethod(..) { //do something}
public void trace(..) { //log something}
Class A
Before
Module deep dive
Spring DAOSpring DAO
JdbcTemplate
intcountOfActorsNamedJoe=this.jdbcTemplate.queryForInt("selectcount(0)fromt_actorswherefirst_name=?",newObject[]{"Joe"});
JdbcTemplate
this.jdbcTemplate.update("deletefromactorwhereid=?",newObject[]{newLong.valueOf(actorId)});
SimpleJdbcTemplate
Stringsql="selectid,first_name,last_namefromT_ACTORwhereid=?";
ParameterizedRowMapper<Actor>mapper=newParameterizedRowMapper<Actor>(){publicActormapRow(ResultSetrs,introwNum)throwsSQLException{Actoractor=newActor();actor.setId(rs.getLong("id"));actor.setFirstName(rs.getString("first_name"));actor.setLastName(rs.getString("last_name"));returnactor;}};
returnthis.simpleJdbcTemplate.queryForObject(sql,mapper,id);
Exceptions
• Spring wraps every jdbc exception
• Same structure for ORM exceptions
• Handle specific database exceptions in a uniform way
• Translate checked exception to unchecked exceptions
Module deep dive
Spring ORMSpring ORM
ORM Integration
• Hibernate
• iBATIS
• JDO
• TopLink
• JPA
Session FactoryConfiguration
<beanid="mySessionFactory"class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"><propertyname="dataSource"ref="myDataSource"/><propertyname="mappingResources"><list><value>product.hbm.xml</value></list></property><propertyname="hibernateProperties"><value>hibernate.dialect=org.hibernate.dialect.HSQLDialect</value></property></bean>
Hibernate TemplateConfiguration
<beanid="myProductDao"class="product.ProductDaoImpl"><propertyname="sessionFactory"ref="mySessionFactory"/>
</bean>
Hibernate Template
publicclassHibernateProductDaoextendsHibernateDaoSupport{
publicCollectionloadProductsByCategory(Stringcategory)throwsDataAccessException,MyException{
returnthis.hibernateTemplate.find("fromtest.Productproductwhereproduct.category=?",category);}
}
Transactions
It’s just more configuration
<beanid="myTxManager"class="org.springframework.orm.hibernate3.HibernateTransactionManager"><propertyname="sessionFactory"ref="mySessionFactory"/></bean>
<aop:config><aop:pointcutid="productServiceMethods"expression="execution(*product.ProductService.*(..))"/><aop:advisoradvice‐ref="txAdvice"pointcut‐ref="productServiceMethods"/></aop:config>
<tx:adviceid="txAdvice"transaction‐manager="myTxManager"><tx:attributes><tx:methodname="increasePrice*"propagation="REQUIRED"/><tx:methodname="someOtherBusinessMethod"propagation="REQUIRES_NEW"/><tx:methodname="*"propagation="SUPPORTS"read‐only="true"/></tx:attributes></tx:advice>
<beanid="myTxManager"class="org.springframework.orm.hibernate3.HibernateTransactionManager"><propertyname="sessionFactory"ref="mySessionFactory"/></bean>
<aop:config><aop:pointcutid="productServiceMethods"expression="execution(*product.ProductService.*(..))"/><aop:advisoradvice‐ref="txAdvice"pointcut‐ref="productServiceMethods"/></aop:config>
<tx:adviceid="txAdvice"transaction‐manager="myTxManager"><tx:attributes><tx:methodname="increasePrice*"propagation="REQUIRED"/><tx:methodname="someOtherBusinessMethod"propagation="REQUIRES_NEW"/><tx:methodname="*"propagation="SUPPORTS"read‐only="true"/></tx:attributes></tx:advice>
Transaction manager
<beanid="myTxManager"class="org.springframework.orm.hibernate3.HibernateTransactionManager"><propertyname="sessionFactory"ref="mySessionFactory"/></bean>
<aop:config><aop:pointcutid="productServiceMethods"expression="execution(*product.ProductService.*(..))"/><aop:advisoradvice‐ref="txAdvice"pointcut‐ref="productServiceMethods"/></aop:config>
<tx:adviceid="txAdvice"transaction‐manager="myTxManager"><tx:attributes><tx:methodname="increasePrice*"propagation="REQUIRED"/><tx:methodname="someOtherBusinessMethod"propagation="REQUIRES_NEW"/><tx:methodname="*"propagation="SUPPORTS"read‐only="true"/></tx:attributes></tx:advice>
Pointcut and Advisor
<beanid="myTxManager"class="org.springframework.orm.hibernate3.HibernateTransactionManager"><propertyname="sessionFactory"ref="mySessionFactory"/></bean>
<aop:config><aop:pointcutid="productServiceMethods"expression="execution(*product.ProductService.*(..))"/><aop:advisoradvice‐ref="txAdvice"pointcut‐ref="productServiceMethods"/></aop:config>
<tx:adviceid="txAdvice"transaction‐manager="myTxManager"><tx:attributes><tx:methodname="increasePrice*"propagation="REQUIRED"/><tx:methodname="someOtherBusinessMethod"propagation="REQUIRES_NEW"/><tx:methodname="*"propagation="SUPPORTS"read‐only="true"/></tx:attributes></tx:advice>
Advice - Propagation properties
Module deep dive
Spring WEBSpring WEB
Web MVC Components
• Controllers
• View Handlers
• Validation
Controller Hierarchy
AbstractController
CommandController
FormController
WizzardController
MultiactionController
Compared to other web frameworks
• Web MVC is very simple
• It’s ‘action’ based
• Close to the request/response model
• It doesn’t have conversational state
Spring Portlets
• Web MVC for JSR-168
• Exactly the same programming model for Portlets and Servlets
• Doesn’t hide the Portlet specific flow
Testing
• Spring Mock• Integration Testing
Spring Mocks
• Mock often used objects
• Request, Response, Session, JNDI etc.
Spring integration testing
• Test Wiring
• Test DAOs
Test DAOs
• Wire beans
• Manage transactions
• Rollback transaction after each test
• Mix Hibernate and plain JDBC in one transaction
DAO test example
@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations={"daos.xml"})publicfinalclassHibernateTitleDaoTests{@AutowiredprivateHibernateTitleDaotitleDao;publicvoidtestLoadTitle()throwsException{Titletitle=this.titleDao.loadTitle(newLong(10));assertNotNull(title);}}
Closed source Spring?
The verdict
• Spring is very complete
• It’s “environment friendly”
• It helps loose coupling
• It’s much better than J2EE
Do we still need it?
• JEE 5 has a similar programming model
• Seam is a much better web framework
Where to start
• http://springframework.org
• Reference documentation
• Spring Pet store
Spring related
• Spring Webflow
• Spring security (acegi)
• Spring webservices
• Spring integration
Enjoy your evening