Spring Framework - Thoughthaus.net

materialisticrampantInternet and Web Development

Nov 10, 2013 (3 years and 9 months ago)

86 views

Spring Framework
Kyle Dyer
MSI Systems Integrators
Starting Facts
•Springis a layered Java/J2EE application
framework, based on code published in “Expert
One-on-One J2EE Design and Development”by
Rod Johnson(Wrox, 2002)
•Open sourceapache license v2.0
•Backed by Bruce Tate-NFJS which is coming
March 10-12.
•Supportavailable from Consultants at
Interface21
What is Spring good for?
Spring seems designed to ease J2EE
development by allowing us access to J2EE
services we want in a clean way via dependency
injectionand helpers. It also allows us in many
casesto avoid creating EJB components by
providing the most useful EJB services via
Aspect Oriented Programmingconcepts.
Values
•J2EE should be easier to use
•Checked exceptions are overusedin Java. A
framework shouldn't force you to catch
exceptions you're unlikely to be able to recover from.
•Testabilityis essential, and a framework such as
Spring should help make your code easier to
test.
•It's best to program to interfacesrather than
classes.
•Plain old Java objects (POJOs)
Three Major Parts
•Dependency Injection Container
•AOP framework
•Lots of goodies –JDBC abstractions, messaging
abstractions, remotingabstractions, transactions,
integration with O/R tools, web MVC
framework, integration with many web UI
frameworks
Dependency Injection
•Article by Martin Fowler
http://www.martinfowler.com/articles/injection.html
•Decouplingis good
•Therefore code to interfaces not implementations
•However, interfaces don’t do anything so if we
want to write programs that dosomething we’ve
got to have implementations of these wonderful
interfaces.
•The DI framework creates the
implementations and injects them into any
bean that needs them.
•Three step process:
–Code up a dependency on an interface
–Create a setter so that Spring can pass in an
implementation
–Tie the implementation to the setter in the
Spring configuration file
public class TaskLister{
private ArrayListTaskDaodao= null;
public TaskLister(){
dao= new ArrayListTaskDao();
}
public List listTasksForToday(){
ArrayListlist = new ArrayList();
Date today = new Date();
Iteratoriter= dao.getAllTasks().iterator();
while (iter.hasNext()){
Task t = (Task) iter.next();
if (today.after(t.getStart())){
list.add(t);
}
}
return list;
}
}
Naive Example –Using Data Access Object (DAO)
public interface TaskDao{
public Task getTask(intid);
public List getAllTasks();
public void insertTask(Taskt);
public void removeTask(intid);
}
Code to Interface
public class TaskLister{
private TaskDaodao= null;
public List listTasksForToday(){
ArrayListlist = new ArrayList();
Date today = new Date();
Iteratoriter= dao.getAllTasks().iterator();
while (iter.hasNext()){
Task t = (Task) iter.next();
if (today.after(t.getStart())){
list.add(t);
}
}
return list;
}
}
Code to Interface
Create a Setter
public class TaskLister{
private TaskDaodao= null;
// skip a bit
public void setDao(TaskDaodao){
this.dao= dao;
}
}
This setter will be used by Spring to inject
the DAO implementation that you define in
the spring configuration.
Spring Configuration
<?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="taskLister"
class="demo.managers.TaskLister">
<property name="dao">
<ref local="taskDao" />
</property>
</bean>
<bean id=taskDao
class=demo.dao.ArrayListTaskDao/>
</beans>
Here is where we
are injecting the
right DAO into the
TaskLister
Client Code
import
org.springframework.context.support.ClassPathXmlApplicationContext;
public class TaskCommand{
public static void main(String[] args) {
ClassPathXmlApplicationContextctx= new
ClassPathXmlApplicationContext("app-context.xml");
TaskListerlister= (TaskLister)
ctx.getBean(taskLister");
System.out.println(
lister.listTasksForToday()
);
}
}
Here is where we are
using the Spring
application context
to get our TaskLister
Spring Persistence
•Replace daofor the TaskListerwith one that gets
records from a database
•Steps:
–Create the new daoimplementation
–Create dependancyon the DataSourceinterface
–Code up the JDBC access using the DataSourceto get
a Connection object
–Inject DataSourceinto Dao via Spring configfile.
–Inject new daointo TaskLister
JdbcDao Class
public class
JdbcTaskDao
implements
TaskDao
{
private DataSourcedataSource= null;
public setDataSource(DataSourceds){
this.dataSource= ds;
}
public List getAllTasks() {
ArrayListresults = new ArrayList();
Connection c = null;
PreparedStatementstmt = null;
ResultSetrs= null;
try {
c = dataSource.getConnection();
stmt = c.prepareStatement(
"select * from KDYER.DEMO_TASK");
rs= stmt.executeQuery();
while (rs.next()){
Task t = new Task();
// populate Task
results.add(t);
}
} catch (SQLExceptione){
e.printStackTrace();
} finally {
if (rs!= null) {
try {
rs.close();
} catch (SQLExceptione) {
e.printStackTrace();
}
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLExceptione) {
e.printStackTrace();
}
}
if (c != null){
try {
c.close();
} catch (SQLExceptione) {
e.printStackTrace();
}
}
}
return results;
}
// skip remaining code for this class
}
Configuration
<beans>
<bean id="taskLister" class="demo.managers.TaskLister">
<property name="dao">
<ref local="taskDao" />
</property>
</bean>
<bean id="taskDao" class="demo.dao.JdbcTaskDao">
<property name="dataSource" ref="myDataSource" />
</bean>
<bean id="myDataSource"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>jdbc/taskDemoDS</value>
</property>
</bean>
</beans>
Just another Data Source
<beans>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"
destroy-method="close">
<property name="driverClassName">
<value>COM.ibm.db2.jdbc.app.DB2Driver</value>
</property>
<property name="url">
<value>jdbc:db2:DEMO</value>
</property>
<property name="connectionProperties">
<props>
<prop key="currentSchema">kdyer</prop>
</props>
</property>
</bean>
</beans>
Spring JdbcTemplate
public class EvenBetterJdbcTaskDaoimplements TaskDao{
private DataSourcedataSource= null;
public void setDataSource(DataSourcedataSource) {
this.dataSource= dataSource;
}
public List getAllTasks() {
final List list= new ArrayList();
JdbcTemplatejdbcTemplate= new JdbcTemplate(dataSource);
jdbcTemplate.query("select* from KDYER.DEMO_TASK",
new RowCallbackHandler(){
public void processRow(ResultSetrs) throws SQLException{
Task t = new Task();
t.setName(rs.getString("name"));
// populate the rest
list.add(t);
}
});
return list;
}
Spring AOP
•Aspects are a way of implementing cross
cutting concerns.
•Join Point: A point during the execution of
a program.
•Advice: Action taken at a particular join
point.
•Point Cut: A set of join points, defined to
specify when an advice should fire. Often
described using regular expressions.
Spring AOP
•Target object: The object instance which is
having it’s method calls intercepted.
•AOP proxy: Object reference that wraps
around the target object and fires the
interceptors.
•Interceptor: Methods are intercepted and
execution is passed to a chain of
interceptors. This is where put the code
which will “advise”target.
AOP Example -Auditing
•New requirement: Each method call that
makes a change to the database should
be audited.
•We could add code to every method that
makes changes –but,
–Will muck up our application’s core
business logic concerns
–Would spread our auditing solution all over
the place making it hard to change
Code example
Transaction Management
•Spring provides a special Transaction AOP
Proxy that can wrap around any POJO
•Provides declarative transaction demarcation to
any method in the target POJO
•Transaction propagation options similar to EJB
CMT: required, supports, mandatory etc.
•Transaction rollback can be configured to
happen automatically when the method throws
certain exceptions.
Transaction Management
•Create a target business object POJO with idea
that each method will happen in a transaction.
•Wrap the POJO in the AOP proxy
•Declare the propagation option for each method
•Declare which exceptions will roll back the
transaction.
•Change the DAOsto get the Connection object
from the
DataSourceUtils.getConnection(DataSourceds)
method.
Code example