0% found this document useful (0 votes)
83 views

Introduction To Spring: Stuart Halloway and Justin Gehtland

Spring is an Alternative to J(2)EE 'Spring' is an Alternative to 'no EJB!''spring' is a 'non-j2ee' language. You may use any code you find here, subject to the terms below. Code citations from other projects are subject to the license(s) appropriate to those projects.

Uploaded by

Gaurav Sharma
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
83 views

Introduction To Spring: Stuart Halloway and Justin Gehtland

Spring is an Alternative to J(2)EE 'Spring' is an Alternative to 'no EJB!''spring' is a 'non-j2ee' language. You may use any code you find here, subject to the terms below. Code citations from other projects are subject to the license(s) appropriate to those projects.

Uploaded by

Gaurav Sharma
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 57

Introduction to Spring

Stuart Halloway and Justin Gehtland


Copyright 2005-6 Relevance, LLC

Introduction to Spring Slide 1 of 51 www.codecite.com


License To Sample Code
This presentation is Copyright 2005-6, Relevance LLC. You may use any code you find here, subject to the terms below. If you want to deliver this
presentation, please send email to [email protected] for permission and details.

Sample code associated with this presentation is Copyright (c) 2005-6 Relevance, LLC (www.relevancellc.com), unless otherwise marked. Code
citations from other projects are subject to the license(s) appropriate to those projects. You are responsible for complying with licenses for code you
use.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to
deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Introduction to Spring Slide 2 of 51 www.codecite.com


Agenda

Myths and Beliefs


Core
dependency injection
configuration
aop
Services
persistence
transactions
mvc
remoting

Introduction to Spring Slide 3 of 51 www.codecite.com


What is Spring

Introduction to Spring Slide 4 of 51 www.codecite.com


Myths

Spring is an Alternative to J(2)EE


'Spring' is Australian for 'No EJB!'
If I have WebLogic/WebSphere/JBoss, Spring is Useless

Introduction to Spring Slide 5 of 51 www.codecite.com


Core Beliefs Driving Spring

Simple, Testable, Components Are Possible


avoid tight coupling
learn from experience
Don't Repeat Yourself (DRY)
aspects are mainstream now

Introduction to Spring Slide 6 of 51 www.codecite.com


Spring and J2EE Agree

Program Against Interfaces


Create Reusable Components
Acquire Services from Containers

Introduction to Spring Slide 7 of 51 www.codecite.com


Use Interfaces to Prevent Tight Coupling

Introduction to Spring Slide 8 of 51 www.codecite.com


Interfaces Are Great, But...

How Do I Create New Objects?


How Do I Configure Objects?
How Do I Manage Objects?

Introduction to Spring Slide 9 of 51 www.codecite.com


Naive Approaches Cause Tight Coupling

Introduction to Spring Slide 10 of 51 www.codecite.com


Inversion of Control (IoC) For Loose Coupling

Introduction to Spring Slide 11 of 51 www.codecite.com


The Main Differences Between Spring and J2EE

Primary IoC Technique


dependency injection in Spring
dependency lookup in J2EE
Spring Very Careful About Dependencies on Itself
lesson learned from J2EE
makes it easy to use Spring with J2EE
makes it easy to use Spring with anything

Introduction to Spring Slide 12 of 51 www.codecite.com


Dependencies on the J2EE Container

Introduction to Spring Slide 13 of 51 www.codecite.com


The Spring Core

Dependency Injection (DI)


Configuration
Aspect Oriented Programming (AOP)
not typically counted among core
we (Relevance) think it will be

Introduction to Spring Slide 14 of 51 www.codecite.com


The Core

Introduction to Spring Slide 15 of 51 www.codecite.com


Dependency Injection in Spring

Get Beans from ApplicationContext


Context Hides Every Possible Source of Dependency
constructor args
new vs. lookup
concrete type

Introduction to Spring Slide 16 of 51 www.codecite.com


DI Code Example
package intro.presenter;

import org.springframework.context.support.FileSystemXmlApplicationContext;

public class DemoEval {


public static void main(String[] args) {
FileSystemXmlApplicationContext ctxt =
new FileSystemXmlApplicationContext("config/demo_eval.xml");
Eval e = (Eval) ctxt.getBean("introSpringEval");
System.out.println(e.getEvent());
}
}

Introduction to Spring Slide 17 of 51 www.codecite.com


DI Configuration Example
<?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="introSpringEval" class="intro.presenter.Eval" singleton="false">
<property name="event" ref="introSpring"/>
</bean>

<bean id="introSpring" class="intro.presenter.Presentation">


<property name="name" value="Intro to Spring"/>
</bean>

<bean id="introDotnetEval" class="intro.presenter.Eval" singleton="false">


<property name="event" ref="introDotnet"/>
</bean>

<bean id="introDotnet" class="intro.presenter.Presentation">


<property name="name" value="Intro to .NET"/>
</bean>

<bean id="validator" class="intro.presenter.Validator"/>

<!-- codecite configure advice -->


<bean id="autoproxy"
class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames">
<value>introSpringEval</value>
</property>
<property name="proxyTargetClass" value="true"/>
<property name="interceptorNames">
<list>
<value>validator</value>
</list>
</property>
</bean>
<!-- codecite configure advice -->
</beans>

Introduction to Spring Slide 18 of 51 www.codecite.com


DI Eliminates Needless Dependencies, But...

What About Necessary Dependencies?


Java provides some help
inheritance, delegation
not nearly enough
Java code, even with DI, is very repetitive
difficult to understand
expensive to maintain

Introduction to Spring Slide 19 of 51 www.codecite.com


Necessary Dependencies, or Cross-Cutting Concerns?

Multiple Classification Hierarchies


single inheritance can handle only one
Generic Services
auditing
transactions
persistence
validation
Per-Instance Variations
static typing forces dependency on everyone

Introduction to Spring Slide 20 of 51 www.codecite.com


Example Cross-Cutting Concern

Introduction to Spring Slide 21 of 51 www.codecite.com


Solution: Aspect Oriented Programming (AOP)

Isolate and Manage Crosscutting Concerns


Modify Code You Don't Control
Bypass the Restrictions of Java's Type System
Make Instance-Specific Code Changes
The Swiss Army Knife of Code Reuse

Introduction to Spring Slide 22 of 51 www.codecite.com


Terminology
Term Definition
Advice code that is woven in (to a pointcut)
Joinpoint point in the execution of an application
Pointcut combination of join points used to place advice
Aspect advice + pointcut
Introduction special case of advice: adding entirely new fields/methods

Introduction to Spring Slide 23 of 51 www.codecite.com


Advice Visualized

Introduction to Spring Slide 24 of 51 www.codecite.com


Aspect Example

Modify Eval Bean To Prevent Negative Values


Do Not Modify Existing Source
write code as advice
Apply Only To Some Evals
use pointcut, config to select which

Introduction to Spring Slide 25 of 51 www.codecite.com


Example: Writing Before Advice
package intro.presenter;

import org.springframework.aop.*;

import java.lang.reflect.Method;

public class Validator implements MethodBeforeAdvice {


public void before(Method method, Object[] objects, Object object)
throws Throwable {
if (objects.length == 1 && objects[0] instanceof Integer) {
if ((Integer)objects[0] <= 0) {
throw new IllegalArgumentException("Cannot be <= 0: " +
objects[0]);
}
}
}
}

Introduction to Spring Slide 26 of 51 www.codecite.com


Example: Configuring Advice
<bean id="autoproxy"
class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames">
<value>introSpringEval</value>
</property>
<property name="proxyTargetClass" value="true"/>
<property name="interceptorNames">
<list>
<value>validator</value>
</list>
</property>
</bean>

Introduction to Spring Slide 27 of 51 www.codecite.com


Example: Invoking Advised Object
package intro.presenter;

import org.springframework.context.support.FileSystemXmlApplicationContext;

public class DemoBadEval {


public static void main(String[] args) {
FileSystemXmlApplicationContext ctxt =
new FileSystemXmlApplicationContext("config/demo_eval.xml");
Eval e = (Eval) ctxt.getBean("introDotnetEval");
System.out.println("Giving negative eval to " + e);
e.setSpeakerEval(-10);
e = (Eval) ctxt.getBean("introSpringEval");
System.out.println("Giving negative eval to " + e);
e.setSpeakerEval(-10);
}

Nothing in the Code Tells Which Beans Are Advised

Introduction to Spring Slide 28 of 51 www.codecite.com


Testing Spring Code

Testing POJOs is Trivial


use plain old JUnit (POJU?)
You Will Also Want To Test In Context
use APIs to weave aspects directly
use production bean config
use test specific bean config
use mock objects

Introduction to Spring Slide 29 of 51 www.codecite.com


Testing Example: Naked and Proxied
package intro.presenter;

import util.TestBase;
import org.springframework.aop.framework.ProxyFactory;

public class TestEval extends TestBase {


private Eval nakedEval;
private Eval proxiedEval;

protected void setUp()


throws Exception {
nakedEval = new Eval();
ProxyFactory pf = new ProxyFactory();
pf.setProxyTargetClass(true);
pf.addAdvice(new Validator());
pf.setTarget(nakedEval);
proxiedEval = (Eval) pf.getProxy();
}

public void testNakedEval() {


nakedEval.setMaterialsEval(5);
assertEquals(5, nakedEval.getMaterialsEval());
nakedEval.setMaterialsEval(-5);
assertEquals(-5, nakedEval.getMaterialsEval());
}

public void testProxiedEval() {


proxiedEval.setMaterialsEval(5);
assertEquals(5, nakedEval.getMaterialsEval());
assertThrows("IllegalArgument", proxiedEval, "setMaterialsEval", -100);
}
}

Introduction to Spring Slide 30 of 51 www.codecite.com


Testing Example: Mock Objects With EasyMock
package intro.presenter;

import util.TestBase;
import static org.easymock.classextension.EasyMock.*;

public class TestEvalController extends TestBase {


public void testEval() {
EvalController ec = new EvalController();
Eval e = createMock(Eval.class);
e.setMaterialsEval(anyInt());
e.setSpeakerEval(anyInt());
replay(e);
ec.fillOutEval(e);
verify(e);
}
}

Introduction to Spring Slide 31 of 51 www.codecite.com


Dependency Injection and Aspects: Pro and Con

Pro
minimize dependencies
minimize repetition
code easy to test
Con
powerful abstractions are a mess when misused
can be difficult to follow, even when used well
lots of XML (for now)

Introduction to Spring Slide 32 of 51 www.codecite.com


Services

Introduction to Spring Slide 33 of 51 www.codecite.com


Data Access

JDBC Support
Hibernate Support
iBatis Support

Introduction to Spring Slide 34 of 51 www.codecite.com


Plain Old JDBC is Simple, Except For...

Connection Setup
Error Handling
Calling close

Introduction to Spring Slide 35 of 51 www.codecite.com


Plain Old JDBC
package intro.jdbc;

import java.sql.*;

public class JdbcRaw {


public static Connection getConnection()
throws ClassNotFoundException, SQLException {
Class.forName("com.mysql.jdbc.Driver");
return DriverManager.getConnection("jdbc:mysql://localhost/hibernate_xt",
"root", "");
}
public static void main(String[] args) {
Connection conn = null;
try {
conn = getConnection();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT title FROM events");
while (rs.next()) {
System.out.println(rs.getString("title"));
}
conn.close();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
if (conn != null) {
try {
conn.close();
} catch (SQLException e1) {
e1.printStackTrace(); //To change body of catch statement use File |
Settings | File Templates.
}
}
}
}
}

Introduction to Spring Slide 36 of 51 www.codecite.com


Spring's JdbcTemplate

Simplified Setup
Closes Resources Automatically
Convenience Methods For
translating exceptions
mapping results to objects
returning Java collections

Introduction to Spring Slide 37 of 51 www.codecite.com


Using JdbcTemplate
package intro.jdbc;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;

import javax.sql.DataSource;
import java.util.*;

public class JdbcWithTemplate {


public static DataSource getDataSource() {
DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://localhost/hibernate_xt");
ds.setUsername("root");
ds.setPassword("");
return ds;
}
public static void main(String[] args) {
JdbcTemplate t = new JdbcTemplate(getDataSource());
List list = t.queryForList("SELECT title FROM events");
for (Iterator it = list.iterator(); it.hasNext();) {
System.out.println(it.next());
}
}
}

Introduction to Spring Slide 38 of 51 www.codecite.com


Using JdbcTemplate With DI
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
<!-- not for production use (use driver with pooling!) -->
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost/hibernate_xt"/>
<property name="username" value="root"/>
<property name="password" value=""/>
</bean>
</beans>
package intro.jdbc;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import org.springframework.jdbc.core.*;

import javax.sql.DataSource;
import java.sql.*;
import java.util.*;

public class JdbcWithTemplateAndDi {


public static void main(String[] args) {
ApplicationContext ctxt = new
FileSystemXmlApplicationContext("config/jdbc_with_template_and_di.xml");
JdbcTemplate t = new JdbcTemplate((DataSource) ctxt.getBean("dataSource"));
List l = t.query("SELECT title FROM events", new RowMapper() {
public Object mapRow(ResultSet rs, int i) throws SQLException {
return rs.getString("title");
}
});
for (Iterator it = l.iterator(); it.hasNext();) {
System.out.println(it.next());
}
}
}

Introduction to Spring Slide 39 of 51 www.codecite.com


Hibernate is Simple, Except For...

Configuration
Calling close

Introduction to Spring Slide 40 of 51 www.codecite.com


Spring Adds DI and HibernateTemplate

Simplified Setup
Closes Resources Automatically
Convenience Methods
Does This Sound Familiar?

Introduction to Spring Slide 41 of 51 www.codecite.com


Hibernate With Dependency Injection
package intro.hibernate;

import org.springframework.context.support.FileSystemXmlApplicationContext;
import org.springframework.context.ApplicationContext;
import org.hibernate.SessionFactory;
import org.hibernate.classic.Session;
import java.util.*;

public class HibernateWithDi {


public static void main(String[] args) {
ApplicationContext ctxt = new
FileSystemXmlApplicationContext("config/hibernate_with_di.xml");
SessionFactory f = (SessionFactory) ctxt.getBean("sessionFactory");
Session sess = f.openSession();
List list = sess.createQuery("from intro.hibernate.Event").list();
for (Iterator iterator = list.iterator(); iterator.hasNext();) {
Event e = (Event) iterator.next();
System.out.println(e.getTitle());
}
sess.close();
}
}
<?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="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="mappingResources">
<list>
<value>intro/hibernate/event.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
</props>
</property>
<property name="dataSource">
<ref bean="dataSource"/>
</property>
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost/hibernate_xt"/>
<property name="username" value="root"/>
<property name="password" value=""/>
</bean>
</beans>

Introduction to Spring Slide 42 of 51 www.codecite.com


Using HibernateTemplate
package intro.hibernate;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.hibernate.SessionFactory;
import java.util.*;

public class HibernateWithDiAndTemplate {


public static void main(String[] args) {
ApplicationContext ctxt = new
FileSystemXmlApplicationContext("config/hibernate_with_di.xml");
HibernateTemplate t = new HibernateTemplate((SessionFactory)
ctxt.getBean("sessionFactory"));
List list = t.find("from intro.hibernate.Event");
for (Iterator iterator = list.iterator(); iterator.hasNext();) {
Event event = (Event) iterator.next();
System.out.println(event.getTitle());
}
}
}

Introduction to Spring Slide 43 of 51 www.codecite.com


HibernateDaoSupport

Base Class For Daos


Properties: sessionFactory and hibernateTemplate
Nothing Complex Here
does encourage good practice

Introduction to Spring Slide 44 of 51 www.codecite.com


Using HibernateDaoSupport
package intro.hibernate;

import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import java.util.List;

public class HibernateDao extends HibernateDaoSupport {


public List getEvents() {
return getHibernateTemplate().find("from intro.hibernate.Event");
}
}
<?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="dao" class="intro.hibernate.HibernateDao">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="mappingResources">
<list>
<value>intro/hibernate/event.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
</props>
</property>
<property name="dataSource">
<ref bean="dataSource"/>
</property>
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost/hibernate_xt"/>
<property name="username" value="root"/>
<property name="password" value=""/>
</bean>
</beans>

Introduction to Spring Slide 45 of 51 www.codecite.com


Spring ACEGI

Security Framework
Pluggable Every Possible Way
Good, Simple Defaults For Web Apps
Highly Recommended

Introduction to Spring Slide 46 of 51 www.codecite.com


ACEGI Simplified

Introduction to Spring Slide 47 of 51 www.codecite.com


ACEGI Complete

Introduction to Spring Slide 48 of 51 www.codecite.com


ACEGI Web Security

ACEGI Designed For Web Apps


many web-specific conveniences
Built Around Servlet Filters
often no code to write
simply configure the filters you want
they must be in the correct order!

Introduction to Spring Slide 49 of 51 www.codecite.com


ACEGI Filters Simplified

Introduction to Spring Slide 50 of 51 www.codecite.com


References

Resources
Codecite (Presentations and Code Samples), http://www.codecite.com
Relevance Consulting and Development, http://www.relevancellc.com/main/services
Relevance Training, http://www.relevancellc.com/main/training
Relevance Weblog, http://blogs.relevancellc.com

Projects Cited
Spring Exploration Application, http://www.codecite.com/projects/download/spring_xt

Introduction to Spring Slide 51 of 51 www.codecite.com

You might also like