Title: Spring Framework
1Spring Framework
2Agenda
- What is Spring?
- Loose coupling with Dependency Injection
- Declarative programming with AOP
- Eliminating Boilerplate with templates
3What is Spring?
4What is Spring?
- Lightweight container framework
- Lightweight - minimally invasive
- Container - manages app component lifecycle
- Framework - basis for enterprise Java apps
- Open source
- Apache licensed
5What its not
- An application server
- Although...theres tcServer, dmServer
- And Spring supports a lot of the EJB3 model
6The Spring Way
- Springs overall theme Simplifying Enterprise
Java Development - Strategies
- Loose coupling with dependency injection
- Declarative programming with AOP
- Boilerplate reduction with templates
- Minimally invasive and POJO-oriented
7A brief history of Spring
- Spring 1.0
- DI, AOP, web framework
- Spring 2.0
- Extensible config, bean scoping, dynamic language
support, new tag library - Spring 2.5
- Annotation-driven, automatic bean discovery, new
web framework, JUnit 4 integration - Spring 3.0
- REST, SpEL, declarative validation, ETag support,
Java-based configuration
8Beyond the framework
- Spring Web Flow
- BlazeDS Integration
- Spring-WS
- Spring Security
- Spring-DM
- dmServer
- Bundlor
- tcServer
- Spring Batch
- Spring Integration
- Spring LDAP
- Spring IDE / STS
- Spring Rich Client
- Spring .NET
- Spring BeanDoc
- Groovy/Grails
9Spring community
- Forum http//forum.springframework.org
- Issues http//jira.springframework.org
- Extensions
- http//www.springframework.org/extensions
- Conferences, user groups, etc
- GET INVOLVED!
10Loose CouplingwithDependency Injection
11Whats wrong here?
- public class Mechanic
- public void fixCar()
- PhillipsScrewdriver tool
- new PhillipsScrewdriver()
- tool.use()
-
12How about now?
- public class Mechanic
- public void fixCar()
- Tool tool
- new PhillipsScrewdriver()
- tool.use()
-
13Any better?
- public class Mechanic
- public void fixCar()
- ToolFactory tf
- ToolFactory.getInstance()
- Tool tool tf.getTool()
- tool.use()
-
14Certainly this is better...
- public class Mechanic
- public void fixCar()
- InitialContext ctx null
- try
- ctx new InitialContext()
- Tool quest (Tool) ctx.lookup(
- "javacomp/env/Tool")
- tool.use()
- catch (NamingException e)
- finally
- if(ctx ! null)
- try ctx.close()
- catch (Exception e)
-
-
-
15Lets try again...
- public class Mechanic
- private Tool tool
- public Mechanic(Tool tool)
- this.tool tool
-
- public void fixCar()
- tool.use()
-
16Or maybe this...
- public class Mechanic
- private Tool tool
- public void setTool(Tool tool)
- this.tool tool
-
- public void fixCar()
- tool.use()
-
17Dependency injection
- Objects are given what they need
- Coupling is low when used with interfaces
- Makes classes easier to swap out
- Makes classes easier to unit test
18DI in Spring
- Several options
- XML
- Annotation-driven
- Java-based configuration
- None are mutually exclusive
19XML-based wiring
- ltbean id"screwdriver"
- class"com.habuma.tools.PhillipsScrewdriver"
/gt - ltbean id"mechanic"
- class"com.habuma.mechanic.AutoMechanic"gt
- ltconstructor-arg ref"screwdriver" /gt
- lt/beangt
ltbean id"screwdriver" class"com.habuma.tools
.PhillipsScrewdriver" /gt ltbean id"mechanic"
class"com.habuma.mechanic.AutoMechanic"gt
ltproperty name"tool" ref"screwdriver"
/gt lt/beangt
20Annotation-based wiring
ltcontextcomponent-scan base-package"com.habu
ma.mechanic" /gt
public class Mechanic private Tool
tool _at_Autowired public void setTool(Tool tool)
this.tool tool public void
fixCar() tool.use()
- public class Mechanic
- _at_Autowired
- private Tool tool
- public void fixCar()
- tool.use()
-
21Java-based configuration
- _at_Configuration
- public class AutoShopConfig
- _at_Bean
- public Tool screwdriver()
- return new PhillipsScrewdriver()
-
- _at_Bean
- public Mechanic mechanic()
- return new AutoMechanic(screwdriver())
-
22Declarative Programming with AOP
23Aspects
- Separate loosely-related behavior
- Objects dont have to do work that isnt their
job - Keeps them cohesive
- Keeps them simple
24Life without AOP
- public void withdrawCash(double amount)
- UserTransaction ut context.getUserTransaction
() - try
- ut.begin()
- updateChecking(amount)
- machineBalance - amount
- insertMachine(machineBalance)
- ut.commit()
- catch (ATMException ex)
- LOGGER.error("Withdrawal failed")
- try
- ut.rollback()
- catch (SystemException syex)
- // ...
-
-
-
25Life with AOP
- public void withdrawCash(double amount)
- try
- updateChecking(amount)
- machineBalance - amount
- insertMachine(machineBalance)
- catch (ATMException ex)
- LOGGER.error("Withdrawal failed")
-
26With some more AOP
- public void withdrawCash(double amount)
- updateChecking(amount)
- machineBalance - amount
- insertMachine(machineBalance)
27Spring AOP
- Comes in 3 forms
- XML-based
- Annotation-based
- Native AspectJ
28AOP Terms
- Aspect
- Advice
- Pointcut
- Joinpoint
29Logging aspect
- public class LoggingAspect
- private static final Logger LOGGER
- Logger.getLogger(LoggingAspect.class)
- public logBefore()
- LOGGER.info("Starting withdrawal")
-
- public logAfterSuccess()
- LOGGER.info("Withdrawal complete")
-
- public logFailure()
- LOGGER.info("Withdrawal failed")
-
30XML-based AOP
- ltbean id"loggingAspect"
- class"LoggingAspect" /gt
- ltaopconfiggt
- ltaopaspect ref"loggingAspect"gt
- ltaopbefore
- pointcut"execution( .withdrawCash(..))"
- method"logBefore" /gt
- ltaopafter-returning
- pointcut"execution( .withdrawCash(..))"
- method"logBefore" /gt
- ltaopafter-throwing
- pointcut"execution( .withdrawCash(..))"
- method"logBefore" /gt
- lt/aopaspectgt
- lt/aopconfiggt
31Annotation-based AOP
- _at_Aspect
- public class LoggingAspect
- private static final Logger LOGGER
- Logger.getLogger(LoggingAspect.class)
- _at_Pointcut("execution( .withdrawCash(..))")
- public void withdrawal()
-
- _at_Before("withdrawal()")
- public logBefore()
- LOGGER.info("Starting withdrawal")
-
- _at_AfterReturning("withdrawal()")
- public logAfterSuccess()
- LOGGER.info("Withdrawal complete")
-
- _at_AfterThrowing("withdrawal()")
- public logFailure()
- LOGGER.info("Withdrawal failed")
ltaopaspectj-autoproxy /gt
32What about transactions?
- lttxadvice id"txAdvice"gt
- lttxattributesgt
- lttxmethod name"withdraw"
- propagation"REQUIRED" /gt
- lttxmethod name"inquire"
- propagation"SUPPORTS"
- read-only"true" /gt
- lt/txattributesgt
- lt/txadvicegt
33Annotating transactions
- lttxannotation-driven /gt
_at_Transactional(propagationPropagation.REQUIRED) p
ublic void withdrawCash(double amount)
updateChecking(amount) machineBalance -
amount insertMachine(machineBalance)
_at_Transactional(propagationPropagation.SUPPORTS,
readOnlytrue) public double inquireBalance(Stri
ng acctNo) // ...
34Eliminating BoilerplatewithTemplates
35Boilerplate
- Exists everywhere
- JDBC
- JNDI
- JMS
- ...all over JEE...
- Lots of plumbing code repeated over and over
36Recognize this?
- public void addSpitter(Spitter spitter)
- Connection conn null
- PreparedStatement stmt null
- try
- conn dataSource.getConnection()
- stmt conn.prepareStatement(SQL_INSERT_SPIT
TER) - stmt.setString(1, spitter.getUsername())
- stmt.setString(2, spitter.getPassword())
- stmt.setString(3, spitter.getFullName())
- stmt.execute()
- catch (SQLException e)
- // do something...not sure what, though
- finally
- try
- if (stmt ! null)
- stmt.close()
-
- if (conn ! null)
- stmt.close()
37Ring any bells?
- InitialContext ctx null
- try
- ctx new InitialContext()
- DataSource ds (DataSource) ctx.lookup(
- "javacomp/env/jdbc/Spitt
erDatasource") - catch (NamingException ne)
- // handle naming exception
-
- finally
- if(ctx ! null)
- try
- ctx.close()
- catch (NamingException ne)
-
38Get the message?
- ConnectionFactory cf
- new ActiveMQConnectionFactory("tcp//localhost
61616") - Connection conn null
- Session session null
- try
- conn cf.createConnection()
- session conn.createSession(false,
Session.AUTO_ACKNOWLEDGE) - Destination destination new
ActiveMQQueue("myQueue") - MessageProducer producer session.createProduce
r(destination) - TextMessage message session.createTextMessage(
) - message.setText("Hello world!")
- producer.send(message)
- catch (JMSException e)
-
- finally
- try
- if(session ! null) session.close()
- if(conn ! null) conn.close()
- catch (JMSException ex)
39JDBC template
ltbean id"dataSource"
class"org.springframework.jdbc.datasource.DriverM
anagerDataSource"gt ltproperty
name"driverClassName" value"db.driver" /gt
ltproperty name"url" value"db.url" /gt
ltproperty name"username" value"db.username"
/gt ltproperty name"password"
value"db.password" /gt lt/beangt
ltbean id"jdbcTemplate"
class"org.springframework.jdbc.core.simple.Simple
JdbcTemplate"gt ltconstructor-arg
ref"dataSource" /gt lt/beangt ltbean
id"spitterDao" class"com.habuma.spitter
.persistence.SimpleJdbcTemplateSpitterDao"gt
ltproperty name"jdbcTemplate" ref"jdbcTemplate"
/gt lt/beangt
- public void addSpitter(Spitter spitter)
- jdbcTemplate.update(SQL_INSERT_SPITTER,
- spitter.getUsername(),
- spitter.getPassword(),
- spitter.getFullName())
- spitter.setId(queryForIdentity())
-
40Spring-flavored JNDI
- ltjeejndi-lookup id"dataSource"
- jndi-name"jdbc/SpitterDatasource"
- resource-ref"true" /gt
41Spring-flavored JNDI
- ltbean id"jmsTemplate"
- class"org.springframework.jms.core.JmsTemplat
e"gt - ltproperty name"connectionFactory"
ref"connectionFactory" /gt - lt/beangt
public void sendMotoristInfo(final Motorist
motorist) jmsTemplate.send(destination,
new MessageCreator()
public Message createMessage(Session session)
throws JMSException
MapMessage message session.createMapMessage()
message.setString("lastName",
motorist.getLastName())
message.setString("firstName", motorist.getFirstNa
me()) message.setString("email",
motorist.getEmail()) return message
)
42Summary
43Spring...
- Is a lightweight container framework
- Simplifies Java development
- POJO-oriented
- Promotes loose coupling with dependency injection
- Supports declarative programming with AOP
- Eliminates boilerplate code with templates
44Where were headed next
- Spring 3 without XML and the ADD developer
- Building web applications with Spring _at_MVC
- Spring JPA Hibernate
- Spring Security
- Grails
- Spring-DM
- Panel discussion