Está en la página 1de 28

Spring Framework Best

Practices
Better architecture by design
JAVAWUG BOF 27, Skills Matter, London
*PP* © 2007

16th July 2007

Peter Pilgrim
Java EE Software Designer Architect
Independent Contractor
Financial Services
Java Champion
http://jroller.com/page/peter_pilgrim
http://jroller.com/page/javawug
Talk Outline

Spring Framework Primary School Class


Spring Version 1.x
Spring Version 2.0
Spring Version 2.1 and JSR 316
Spring Hints & Tips
Summary

2
What is Spring?

Managed Dependency Injection Framework


Life-cycle of POJOS
Dependency Injection for JavaBeans & Interfaces
Plethora of Utility APIs and idioms

3
What is Spring Version 1?

Simplifying J2EE Development

Dynamic Core Spring Data


AOP Access

Bean Factory
Container
MVC Remoting

Declarative
Mail Scheduling
TX

4
What is Spring Version 2?

Simplifying J(2)EE Development


Data
AspectJ
Access
Libraries Core Spring

Dynamic Java 5
AOP
Bean Factory
Container Remoting
Servlet MVC
Annotations (TX) Task
Portlet MVC Executor
XML Namespaces Scripting Languages
Tag Libs
Declarative
Scheduling
Mail TX
5
What is expected in Spring Version 2.1?

Simplifying Java EE Development

AspectJ Familiar Data


Core Spring Access
Integration
Bean Factory Alternative Data
OSGi Modules Access
Dynamic Container
AOP
Annotation Driven Injection
Java EE 5
Servlet MVC Annotation Componentisation
Remoting
Annotation TX
Portlet MVC
Task
Extra XML Executor

Tag Libs Namespaces

Declarative
Spring Security Mail TX Scheduling

6
Goals of Spring 2.0

Backwards compatible
Annotation Driven Transactions
Simplified Java 5 Support
XML Namespace extension for ease-of-configuration
Improved JMS Messaging, local and XA transactions
Task Executor
AspectJ library support
JPA Integration
Portlet MVC

7
Goals of Spring 2.1

OSGi is the biggest value add


Module JARS
Special OSGi XML namespace
Annotation Driven Injection
Spring Back-ends (JCA and LDAP support)
Enhanced JPA support

8
Goals of Spring 2.1

OSGi is the biggest value add


Module JARS
Special OSGi XML namespace
Annotation Driven Injection
Spring Back-ends (JCA and LDAP support)
Enhanced JPA support

9
Future of Spring Development Java EE JSR 316

Eventually we will be locked into Spring, but not yet!!!


Spring OSGi does obscure the raw APIs
Java EE 6 has a new JSR 316
Java EE may incorporate Spring's ideas
Modularisation of Java EE (JSR 277 and 294)
JSR 277 Java Module System
JSR 294 Improved Modularity Support
OSGi forces future EE architects to research new
“materials” for building software

10
Configuration of Transactions: Manager & Advice

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="...">

<tx:advice id="txAdvice" transaction-manager="txManager">


<tx:attributes>
<tx:method name="get*" read-only="true" />
<tx:method name="find*" read-only="true" />
<tx:method name="*" />
</tx:attributes>
</tx:advice>

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

11
Configuration of Transactions: Pointcuts

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="...">

<aop:config>
<aop:pointcut id="projectServiceOperation"
expression="execution(* websitetracker.service.*.*(..))" />
<aop:advisor advice-ref="txAdvice"
pointcut-ref="projectServiceOperation" />
</aop:config>
<aop:config>...</aop:config>
...
</beans>

12
Configuration: Hibernate Session Factory

<beans ...>
<bean id="sessionFactory" class="org.springframework.orm.
hibernate3.LocalSessionFactoryBean">
<property name="mappingResources">
<list>
<value>websitetracker/domain/IpAddressReverse.hbm.xml</value>
<value>websitetracker/domain/Website.hbm.xml</value>
</list></property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.generate_statistics">false</prop>
</props></property>
<property name="dataSource"><ref bean="dataSource"/></property>
<property name="eventListeners">
<map>
<entry key="merge">
<bean class="org.springframework.orm.hibernate3.support.
IdTransferringMergeEventListener" />
</entry></map></property>
</bean> ...
</beans>
13
Configuration: Hibernate DAO & Services

<beans ...>

<bean id="hibernateTemplate" class="org.springframework.


orm.hibernate3.HibernateTemplate">
<property name="sessionFactory">
<ref local="sessionFactory" />
</property>
</bean>

<bean id="ipAddressReverseDao"
class="websitetracker.dao.IpAddressReverseDao" >
<property name="sessionFactory" ref="sessionFactory" />
</bean>

<bean id="trackReportService"
class="websitetracker.engine.impl.TrackReportServiceImpl" >
<property name="hibernateTemplate"
ref="hibernateTemplate" />
</bean> ...
</beans>

14
Multiple Application Contexts

Parent and Child bean factory contexts can help modularise


complexity
ApplicationContexts can retrieve wildcarded configuration
files.
For Spring managed EJBs and MDB prefer to use
ContextSingletonBeanFactoryLocator

public class StartUpBean extends


AbstractStatelessSessionBean {
public boolean start( ... )
setBeanFactoryLocator(
ContextSingletonBeanFactoryLocator
.getInstance(“classpath:fitrader-context.xml”));
setBeanFactoryLocatorKey(“FI-TRADER”);
return true;
}

15
Define A Master Application Context

<!-- “fitrader-context.xml” -->


<beans ...>
<!-- defines the entire container context -->
<bean id="FI-TRADER" class="org.springframework.context.
support.ClassPathXmlApplicationContext">
<constructor-arg index="0">
<list>
<!-- service layer -->
<value>fitrader/service/beans-context-service.xml</value>
<!-- dao layer -->
<value>fitrader/dao/beans-context-dao.xml</value>
<!-- Transaction Manager -->
<value>fitrader/dao/tx/beans-context-transaction.xml</value>
<!-- AOP -->
<value>fitrader/aop/beans-context-aop.xml</value>

</list>
</constructor-arg>
<constructor-arg index="1"><value>true</value></constructor-arg>
</bean>
</beans>

16
Share Contexts Among Spring Managed EJBs

Standard Spring managed EJB examples from books create


and retrieve application contexts separately
Consumes memory per deployment and EJB instance!
Arrange for Spring managed EJBs to retrieve master
application context instead
Share application context Message Driven Beans especially
with point-to-point queue

17
Spring Managed EJB Example

public class TradeRouteProcessorRemoteEJB


extends AbstractStatelessSessionBean
implements ITradeRouteProcessor
{
private static final String BEAN_NAME = "tradeRouteProcessor";
private ITradeRouteProcessorScheduler delegate;

public TradeRouteProcessorRemoteEJB() {
super();
setBeanFactoryLocator(
ContextSingletonBeanFactoryLocator
.getInstance(“classpath:fitrader-context.xml”));
setBeanFactoryLocatorKey(“FI-TRADER”);
}

protected void onEjbCreate() throws CreateException {


delegate = (ITradeRouteProcessor)
getBeanFactory().getBean( BEAN_NAME);
}
...
}

18
Test Driven Development

Write to Java interfaces or refactor them out


Consider EasyMock for functional testing
AbstractSpringDatabaseTestCase is a great
class to extend for an application database unit test
Tactile techniques can help insert dummy data for test
purposes. (JdbcTemplate)

19
Easy Mock Advice

Consider a base test class for functional testing


Pull up useful DAO & Service classes in the base class
Refactor common ground in concrete classes
Write creational methods on the base classes
Call EasyMock.verify() !!!

20
Maven 2.0 Spring Framework Java EE Setup

Eclipse IDE with Maven 2.0, Spring & Hibernate


issues (prefer parallel project structure)
Configure a general application context
Please store under src\main\resources!
Configure at least one test application context
Please store under src\test\resources!
Organise multiple file support for large applications
Install into local repository frequently!
Select all projects and hit F5!! (Grab a Biscuit and tea)
Prefer Profiles to filtered resources! Eclipse tramples.

21
A Generic DAO

Java 5 makes strong-typed collections easier


We can write a generic DAO
We can use the auto-complete feature in our IDEs
We are less likely to make errors in RTTI / casting!
Extendible to named queries and criterion

22
Generic DAO Interface

public interface IPersistenceDao<E, PK extends Serializable> {

public abstract void saveOrUpdate(E transientInstance);


public abstract void attachDirty(E instance);
public abstract void attachClean(E instance);
public abstract void delete(E persistentInstance);
public abstract E merge(E detachedInstance);
public abstract E findById(PK id);
public abstract List<E> findByExample(E instance);
}

23
Abstract Persistence DAO

public abstract class AbstractPersistenceDao<E, PK extends Serializable>


extends HibernateDaoSupport
implements IPersistenceDao<E, PK> {

private Class<E> type;

public AbstractPersistenceDao( Class<E> type ) {


super(); this.type = type; }
public void saveOrUpdate(E transientInstance) {
getHibernateTemplate().saveOrUpdate(transientInstance);
}
public E findById(PK id) {
logger.debug("getting "+type.getName()+" instance with id: " + id);
return (E) getHibernateTemplate().get( packageClassName, id);
}
...
}

24
Concrete Generic DAO

public class IpAddressReverseDao extends


AbstractPersistenceDao<IpAddressReverse,Integer> {

public IpAddressReverseDao() {
super( IpAddressReverse.class );
}

@SuppressWarnings("unchecked")
public List<IpAddressReverse> getAll() {
return getHibernateTemplate().find(
"select i from IpAddressReverse as i");
}

...
}

25
Executive Summary

Review of Spring Framework 2.0 / 2.1


Discussion about the future of this framework
Competing frameworks such as Google Guice
Relevance to modularisation and architectural assembly
Sharing application contexts
Testing
Generic DAO

26
Time for Questions?

Q&A

27
Illustration

28

También podría gustarte