Sie sind auf Seite 1von 19

The Spring Framework:

A brief introduction to Inversion of Control

James Brundege

www.synaptocode.com

What is Spring?
2 Things: An Inversion of Control (IoC) Container

Utilities that provide a consistent (and simple!) API to many other technologies (JDBC, ORM, AOP, Declarative Transactions, etc)

Guiding Principles of Spring


Minimize dependencies on Spring
Minimize dependencies between all layers of an application. All application code should be testable, without an application server or other complex environment Fully factor the APIs (the 90% case should be accomplished in one line of code!)

What is Inversion of Control (IoC)?


(besides yet another confusing term for a simple concept) IoC is all about Object dependencies.

Traditional "Pull" approach: Direct instantiation Asking a Factory for an implementation Looking up a service via JNDI
"Push" approach: Something outside of the Object "pushes" its dependencies into it. The Object has no knowledge of how it gets its dependencies, it just assumes they are there.

The "Push" approach is called "Dependency Injection".

The BookDemo Application:


(A simple CRUD app)
User Interface

Domai n Model

Service Layer

Data Access Layer

DB

Pull Example
public class BookDemoServicePullImpl implements BookDemoService { public void addPublisherToBook(Book book) { BookDemoFactory factory = BookDemoFactory.getFactory(); BookDemoDao dao = factory.getBookDemoDao();

String isbn = book.getIsbn(); if (book.getPublisher() == null && isbn != null) { Publisher publisher = dao.findPublisherByIsbn(isbn); book.setPublisher(publisher); } }
}

Push Example
(Dependency Injection)
public class BookDemoServiceImpl implements BookDemoService { private BookDemoDao dao; public void addPublisherToBook(Book book) { String isbn = book.getIsbn(); if (book.getPublisher() == null && isbn != null) { Publisher publisher = dao.findPublisherByIsbn(isbn); book.setPublisher(publisher); } } public void setBookDemoDao(BookDemoDao dao) { this.dao = dao; } }

BookDemoService Unit Test

Definitions
Dependency Injection is the act of injecting dependencies into an Object.
Inversion of Control is the general style of using Dependency Injection to wire together application layers. Hence Spring is an Inversion of Control container. That is, it is a container that handles Dependency Injection for you.

Why is Dependency Injection better?


2 reasons: Loose Coupling Testability

Loose Coupling is improved because you don't hard-code dependencies between layers and modules. Instead you configure them outside of the code. This makes it easy to swap in a new implementation of a service, or break off a module and reuse it elsewhere.
Testability is improved because your Objects don't know or care what environment they're in as long as someone injects their dependencies. Hence you can deploy Objects into a test environment and inject Mock Objects for their dependencies with ease.

How Spring does Inversion of Control


Write a configuration file in which you name concrete "beans" for the interfaces between your layers. "Wire" the application together by stating which beans are dependent on each other. Instantiate a Spring object called an ApplicationContext. This is a type of bean factory that will instantiate all your other beans and handle dependency injection.

Example Spring applicationContext.xml


<beans> <bean id="bookDemoDao" class="com.bookdemo.dao.hibernate.BookDemoDaoHibernateImpl"> <property name="sessionFactory"> <ref local="sessionFactory"/> </property> </bean> <bean id="bookDemoService" class="com.bookdemo.service.impl.BookDemoServiceImpl"> <property name="bookDemoDao"> <ref bean="bookDemoDao"/> </property> </bean> </bean>

Bootstapping the IoC container


To start an app using IoC: Create an ApplicationContext object and tell it where applicationContext.xml is.
ApplicationContext appContext = new ClassPathXmlApplicationContext("classpath*:applicationContext.xml");

This just has to be done once on startup, and can be done in the main() method or whatever code bootstraps the application.

Bootstapping the IoC container


The appContext holds a single copy of each bean declared in applicationContext.xml, so you could ask the Context for any bean by name:
MyService service = (MyService)appContext.getBean("myService");

But don't! That is a "Pull" technique that treats the ApplicationContext like a Factory. Instead, make sure that applicationContext.xml connects every bean to every other bean that needs it. None of the beans thus have a dependency on spring.jar

Bootstapping the IoC container


For web applications the situation is simpler: Web applications are bootstrapped by the web container based on the web.xml file. Hence creating an ApplicationContext on startup is as simple as a single declaration in web.xml:
<listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener>

A Spring app with no dependencies on Spring?


When bootstrapping spring from web.xml, there are only two pieces: The applicationContext.xml file A single tag within web.xml Not a single line of Java code! Therefore, not one of your custom classes has a dependency on spring.jar

The BookDemo App

What else has Spring got?


Spring provides either implementations or fully-factored API wrappers over these technologies:

JDBC and DAOs ORM: Hibernate, iBatis, TopLink and others Declarative Transaction Support (without a full J2EE
app server) Aspect-Oriented Programming Remote calls and Web Services (Axis) EJBs

Resources
Spring Website: http://www.springframework.org/
Download Spring with sample applications:
http://prdownloads.sourceforge.net/springframework/spring-framework-1.2.8-withdependencies.zip?download

Rod Johnson's book on Spring:


http://www.powells.com/biblio?PID=719&cgi=product&isbn=0764574833

Wikipedia:
http://en.wikipedia.org/wiki/Spring_Framework_%28Java%29 EasyMock: http://www.easymock.org/ Echo2 (Rich Web Inteface framework) http://www.nextapp.com/platform/echo2/echo/

Das könnte Ihnen auch gefallen