SlideShare a Scribd company logo
Introduc)on to Spring
Ilio Catallo - info@iliocatallo.it
Outline
• What is Dependency Injec2on?
• The Spring Framework
• Wri2ng applica2ons in Spring
• References
What is Dependency Injec1on?
Components
Applica'ons typically consist of components that work together to
form what the user sees as a coherent whole
Movie rental
Assume that we need to write a component that provides a list of
movies directed by a par5cular director1
1
This use case is an adapta/on from the Mar/n Fowler's seminal example on Inversion of Control (see references)
Movie rental
Moreover, assume we are told that movies are currently being
stored in a comma delimited file
MovieService
A"er much delibera/on, we delineate the following component,
which we decide to call MovieService
public class MovieService {
private CSVMovieRepository repository;
public List<Movie> moviesDirectedBy(String directorName) { ... }
}
MovieService
Note that MovieService depends on CSVMovieRepository
public class MovieService {
private CSVMovieRepository repository;
public List<Movie> moviesDirectedBy(String directorName) { ... }
}
CSVMovieRepository
CSVMovieRepository is an addi'onal component that abstracts
the comma delimited file containing the list of movies
public class CSVMovieRepository {
public CSVMovieRepository(String filename) { ... }
public List<Movie> findAll() { ... }
}
The moviesDirectedBy use case
An immediate implementa,on of moviesDirectedBy() is
therefore as follows:
public List<Movie> moviesDirectedBy(String directorName) {
List<Movie> movies = repository.findAll();
Iterator<Movie> it = movies.iterator();
while (it.hasNext()) {
Movie movie = it.next();
if (!movie.getDirector().equals(directorName))
it.remove();
}
return movies;
}
The moviesDirectedBy use case
Alterna(vely, we can use the Stream API in order to obtain a terser
implementa(on
public List<Movie> moviesDirectedBy(String directorName) {
repository.findAll()
.stream()
.filter(m -> m.getDirector().equals(directorName))
.collect(Collectors.toList());
}
MovieService class
public class MovieService {
private CSVMovieRepository repository;
public MovieService() {
this.repository = new CSVMovieRepository("movies.csv");
}
public List<Movie> moviesDirectedBy(String directorName) {
List<Movie> movies = repository.findAll();
Iterator<Movie> it = movies.iterator();
while (it.hasNext()) {
Movie movie = it.next();
if (!movie.getDirector().equals(directorName))
it.remove();
}
return movies;
}
}
Job done?
Unit tes(ng MovieService
Assume that we now want to unit test MovieService
public class MovieServiceTest {
@Test
public void moviesDirectedByTest() {
...
}
}
Unit tes(ng MovieService
We want to ensure the correctness of moviesDirectedBy() by
checking its output against a set of controlled movies
Unit tes(ng MovieService
For instance, given the following data
Sophia Coppola, Lost in Translation
Christopher Nolan, Inception
Christopher Nolan, The Dark Knight
Unit tes(ng MovieService
We want to test if moviesDirectedBy("Sophia Coppola")
returns the expected output
@Test
public void moviesDirectedByTest() {
List<Movie> movies = service.moviesDirectedBy("Shopia Coppola");
assertTrue(movies.length == 1);
assertTrue(movies.get(0).getDirector().equals("Sophia Coppola"));
assertTrue(movies.get(0).getTitle().equals("Lost in Translation"));
}
MockMovieRepository
We can therefore devise a MockMovieRepository:
public class MockMovieRepository {
public List<Movie> findAll() {
return Arrays.asList(
new Movie("Sophia Coppola", "Lost in Translation"),
new Movie("Christopher Nolan", "Inception"),
new Movie("Christopher Nolan", "The Dark Knight")
);
}
}
Unit tes(ng MovieService
To use our test data, we need to replace CSVMovieRepository
with MockMovieRepository
Unit tes(ng MovieService
We need to unplug MovieService from CSVMovieRepository
Unit tes(ng MovieService
However, there is no way to replace CSVMovieRepository with
MockMovieRepository
public class MovieService {
private CSVMovieRepository repository;
public MovieService() {
this.repository = new CSVMovieRepository("movies.csv");
}
}
Unit tes(ng MovieService
This is because MovieService instan-ates its own dependency
public class MovieService {
private CSVMovieRepository repository;
public MovieService() {
this.repository = new CSVMovieRepository("movies.csv");
}
}
MovieService cannot be tested
Thus, we found out that our solu1on is not unit testable
public class MovieService {
private CSVMovieRepository repository;
public MovieService() {
this.repository = new CSVMovieRepository("movies.csv");
}
}
What could ever happen?
¯_( )_/¯
What could ever happen?
Variability
Apart from testability, we may face an even bigger issue with our
solu7on
Variability
Assume that we are suddenly been told that from now on movies
are going to be stored in a rela%on database
Variability
That requires changing MovieService, even though the real
change involves a different component
public class MovieService {
public SQLMovieRepository repository;
public MovieService() {
this.repository = new SQLMovieRepository(...);
}
...
}
Obtaining the movie list
This appears even more suspicious if we no2ce that the
implementa2on of moviesDirectedBy() does not change
public List<Movie> moviesDirectedBy(String directorName) {
List<Movie> movies = repository.findAll();
...
}
Obtaining the movie list
As a ma&er of fact, MovieService does not need to know how
the movies are stored
public List<Movie> moviesDirectedBy(String directorName) {
List<Movie> movies = repository.findAll();
...
}
Obtaining the movie list
There are many different ways of storing the movie list
• Database
• File system
• Remote web service
MovieRepository as an interface
We can explicitly model this variability by defining a
MovieRepository interface with a unique method
public interface MovieRepository {
List<Movie> findAll();
}
MovieRepository as an interface
Each MovieRepository implementa-on has its own way of
retrieving the data
public class SQLMovieRepository implements MovieRepository {...}
public class CSVMovieRepository implements MovieRepository {...}
public class RESTMovieRepository implements MovieRepository {...}
External dependency
Instead of le,ng MovieService look up the right
implementa5on, we provide it as an external dependency
public class MovieService {
private MovieRepository repository;
public MovieService(MovieRepository repository) {
this.repository = repository;
}
...
}
Composing objects
We can now provide different implementa2ons of
MovieRepository to MovieService
public class MovieService {
private MovieRepository repository;
public MovieService(MovieRepository repository) {
this.repository = repository;
}
...
}
Composing objects
This allows different developers to reuse the same components in
different situa5ons
public class MovieService {
private MovieRepository repository;
public MovieService(MovieRepository repository) {
this.repository = repository;
}
...
}
Dependency inversion principle
What we did in the above is a direct applica3on of the dependency
inversion principle
Dependency inversion principle
1. High-level modules should not depend on low-level modules.
Both should depend on abstrac:ons
2. Abstrac:ons should not depend upon details. Details should
depend upon abstrac:ons
Both should depend on abstrac1ons
+--------------+ +-----------------+
| | | |
| MovieService +----------> MovieRepository |
| | | |
+--------------+ +--------^--------+
|
|
|
+---------+----------+
| |
| SQLMovieRepository |
| |
+--------------------+
Details should depend upon abstrac2ons
Details should depend upon abstrac2ons
+--------------------------------------------------+
| |
| +--------------+ +-----------------+ |
| | | | | |
| | MovieService +----------> MovieRepository | |
| | | | | |
| +--------------+ +--------^--------+ |
| | |
+--------------------------------------------------+
|
+---------+----------+
| |
| SQLMovieRepository |
| |
+--------------------+
Testability
As a welcome byproduct, we gain the possibility of tes8ng
MovieService
@Test
public void moviesDirectedByTest() {
MovieService ms = new MovieService(new MockMovieRepository());
List<Movie> movies = ms.moviesDirectedBy("Sophia Coppola");
assertTrue(movies.length == 1);
assertTrue(movies.get(0).getDirector().equals("Sophia Coppola"));
assertTrue(movies.get(0).getTitle().equals("Lost in Translation"));
}
Job done?
Deciding for a MovieRepository
At a certain point we need to decide for a specific implementa-on
of MovieRepository
Factories
To this end, we write a factory class, whose responsibility is to
provide fully-constructed MovieService objects
Factories
For instance, we could devise the following simple factory2
public class MovieServiceFactory {
public MovieService create(String type) {
if (type.equals("CSV")) return new MovieService(new CSVMovieRepository(...));
if (type.equals("SQL")) ...
return null;
}
}
2
Here, we are using the so called simple factory pa/ern. Although it is in turn sub-op9mal, we decided for this
pa<ern because of the similarity of its interface with that of Spring's own factories
Factories
We can finally obtain a fully-constructed MovieService
public static void main(String[] args) {
...
MovieService service = factory.create("SQL");
List<Movie> movies = service.moviesDirectedBy("Sophia Coppola");
}
Wiring objects
Developers of the applica0on are in charge of wiring the different
components together
Wiring objects
That is, developers are in control of the assembly phase of the
applica5on components
Wiring objects
Developers would happily give up this control to someone else
Wiring objects
That is, developers would happily stop wri$ng factories
Wiring objects
We would like a 3rd
-party factory to take care of crea0ng and
wiring the different objects of the applica0on on our behalf
MovieService movieService = externFactory.getComponent("SQL");
Dependency Injec+on
Dependency injec+on (DI) is a pa*ern whereby the responsibility
of crea7ng and wiring applica7on objects is deferred to a 3rd
-party
factory
Dependency Injec+on
Namely, the 3rd
-party factory will:
• Instan'ate components
• Provide dependencies to each component
• Manage the lifecycle of each component
The Spring framework
The Spring framework
Spring is a Java framework that provides comprehensive
infrastructure support for developing Java applica6ons
Spring DI Containers
In Spring, applica-on components are instan&ated and managed
directly by the framework
Spring DI Containers
Objects live within a dependency-inversion container
+-------------------------------+
| +-------+ +-------+ |
| | | | | |
| | A +------> B | |
| | | | | |
| +---^---+ +---^---+ |
| | | |
| | | |
| +---+---+ | |
| | | | |
| | C +----------+ |
| | | |
| +-------+ |
+-------------------------------+
Spring DI container
Spring DI Containers
Such a DI container plays the role of the 3rd
-party factory
+-------------------------------+
| +-------+ +-------+ |
| | | | | |
| | A +------> B | |
| | | | | |
| +---^---+ +---^---+ |
| | | |
| | | |
| +---+---+ | |
| | | | |
| | C +----------+ |
| | | |
| +-------+ |
+-------------------------------+
Spring DI container
Spring DI Containers
It is responsible for instan&a&ng and assembling the objects
+-------------------------------+
| +-------+ +-------+ |
| | | | | |
| | A +------> B | |
| | | | | |
| +---^---+ +---^---+ |
| | | |
| | | |
| +---+---+ | |
| | | | |
| | C +----------+ |
| | | |
| +-------+ |
+-------------------------------+
Spring DI container
Spring beans
A bean is an applica)on object that is instan)ated, and otherwise
managed by a Spring DI container
+-------------------------------+
| +-------+ +-------+ |
| | | | | |
| | A +------> B | |
| | | | | |
| +---^---+ +---^---+ |
| | | |
| | | |
| +---+---+ | |
| | | | |
| | C +----------+ |
| | | |
| +-------+ |
+-------------------------------+
Spring DI container
Spring DI Containers
Spring comes with two families of containers:
• Containers that implement the BeanFactory interface
• Containers that implement the ApplicationContext
interface
BeanFactory
The BeanFactory interface provides basic support for DI
ApplicationContext
The ApplicationContext interface extends BeanFactory,
providing addi4onal func4onali4es
• Interna(onaliza(on support
• The ability to load resource file
Bean retrieving
The ApplicationContext interface models a sophis2cated
implementa2on of the factory pa*ern
T getBean(String name, Class<T> requiredType)
Bean retrieving
By using the getBean() method, developers can retrieve
instances of the applica7on beans
T getBean(String name, Class<T> requiredType)
Bean retrieving
Example of bean retrieving:
ApplicationContext c = new ClassPathXmlApplicationContext("ex1.xml");
MovieService movieService = c.getBean("SQL", MovieService.class);
Bean retrieving
ClassPathXmlApplicationContext is an implementa+on of
ApplicationContext
ApplicationContext c = new ClassPathXmlApplicationContext("ex1.xml");
MovieService movieService = c.getBean("SQL", MovieService.class);
Introduction To Spring
Configura)on metadata
The container gets instruc/ons on what objects to instan/ate and
configure by reading some configura)on metadata
+ Business objects
|
|
|
|
+---------v---------+
| |
| Spring |
+-------------> Container |
| |
Configuration +---------+---------+
metadata |
(e.g., XML file) |
|
v Fully configured
system
Configura)on metadata
Through the configura.on metadata, the developer tells the Spring
container how to assemble objects
+ Business objects
|
|
|
|
+---------v---------+
| |
| Spring |
+-------------> Container |
| |
Configuration +---------+---------+
metadata |
(e.g., XML file) |
|
v Fully configured
system
Configura)on metadata
The configuring metadata can be represented in:
• XML
• Java annota,on
• Java code
Configura)on metadata
The configura-on metadata ex1.xml is loaded from the
CLASSPATH
ApplicationContext c = new ClassPathXmlApplicationContext("ex1.xml");
MovieService movieService = c.getBean("SQL", MovieService.class);
Dependencies vs. business logic
The DI Container allows decoupling the specifica(on of
dependencies from the actual program logic
Wri$ng applica$ons with Spring
POJOs
Many Java frameworks require developers to extend classes or
implement interfaces provided by the framework itself
public class MyServlet extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response);
public void doPost(HttpServletRequest request,
HttpServletResponse response);
public void init();
public void destroy();
}
POJOs
Spring beans are instead Plain Old Java Objects (POJOs)
public class MovieService {
private MovieRepository repository;
public MovieService(MovieRepository repository) {
this.repository = repository;
}
...
}
POJOs
Because of this, components in a Spring-based applica8on o9en
have no indica(on that they are being used by Spring
Movie rental
Assume that we want to take advantage of the Spring framework
for our movie rental applica.on
Movie rental
We need to instruct the Spring DI container about the dependency
between MovieService and MovieRepository
+--------------+ +-----------------+
| | | |
| MovieService +----------> MovieRepository |
| | | |
+--------------+ +--------^--------+
|
|
|
+---------+----------+
| |
| SQLMovieRepository |
| |
+--------------------+
Configuring the container
We need to configure Spring to tell it what beans it should contain,
and how to wire those beans
+---------------------------------------------------+
| +--------------+ +-----------------+ |
| | | | | |
| | MovieService +----------> MovieRepository | |
| | | | | |
| +--------------+ +--------^--------+ |
| | |
| | |
| | |
| +---------+----------+ |
| | | |
| | SQLMovieRepository | |
| | | |
| +--------------------+ |
+---------------------------------------------------+
Spring DI container
Configuring the container
For now, we will focus on tradi2onal XML configura-on
The <beans> element
The root element of the Spring configura4on file is the <beans>
element
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/
spring-beans.xsd">
<!-- CONFIGURE APPLICATION BEANS HERE -->
</beans>
The <bean> element
Each applica)on bean is associated with a <bean> element in the
XML configura)on file
<bean id="inMemoryMovieRepository”
class="it.polimi.awt.repository.InMemoryMovieRepository">
...
</bean>
The <bean> element
Every bean has one (or more) id a0ribute, and a class a0ribute
<bean id="inMemoryMovieRepository”
class="it.polimi.awt.repository.InMemoryMovieRepository">
...
</bean>
The <bean> element
Namely:
• If more iden,fiers are specified, the extra ones are considered as
aliases
• The class a8ribute could either specify the class of the bean to
be constructed or the name of a sta,c factory method
How to inject dependencies
In Spring, dependencies are injected through:
• Construc*on-based injec*on
• Se4er-based injec*on
• Arguments to a factory method
Constructor-based injec1on
Constructor-based injec1on is accomplished by the container
invoking the bean constructor
<bean id="movieService" class="it.polimi.awt.service.MovieService">
<constructor-arg ref="inMemoryMovieRepository"/>
</bean>
Constructor-based injec1on
The <constructor-arg> element allows injec0ng a dependency
through a constructor call
<bean id="movieService" class="it.polimi.awt.spring.MovieService">
<constructor-arg ref="inMemoryMovieRepository"/>
</bean>
Se#er-based injec/on
Se#er-based injec/on is accomplished by the container calling
se3er methods on the bean3
<bean id="lostInTranslation" class="it.polimi.awt.domain.Movie">
<property name="title" value="Lost in Translation"/>
<property name="director" value="Sophia Coppola"/>
</bean>
3
As we will see, Movies are domain objects, which usually do not need injec5on. Here, we are doing this for the
sole sake of presen5ng an example of se>er-based injec5on
Se#er-based injec/on
The <property> element injects the dependency by calling the
property se5er
<bean id="lostInTranslation" class="it.polimi.awt.domain.Movie">
<property name="title" value="Lost in Translation"/>
<property name="director" value="Sophia Coppola"/>
</bean>
Constructor vs. se-ers
As a rule of thumb, use constructor arguments for mandatory
dependencies and se6ers for op*onal dependencies
Spring beans vs. JavaBeans
Despite the similar name, keep in mind that a DI container is not
limited to JavaBeans4
and it can manage virtually any class
4
Recall that JavaBeans are objects with i) only a default constructor; and ii) appropriate ge<ers and se<ers
Introduction To Spring
Introduction To Spring
References
References
• Mar%n Fowler, Inversion of Control and Dependency Injec%on
pa;ern
• SpringSource, Spring Framework Reference
• Craig Walls, Spring in Ac%on (3rd Edi%on), Manning Publica%ons

More Related Content

PDF
Effective CMake
PDF
CMake: Improving Software Quality and Process
PDF
CMake - Introduction and best practices
PPT
Patni Hibernate
PPT
PPT
15 jpaql
PDF
JPQL/ JPA Activity 2
 
ODP
Working with jpa
Effective CMake
CMake: Improving Software Quality and Process
CMake - Introduction and best practices
Patni Hibernate
15 jpaql
JPQL/ JPA Activity 2
 
Working with jpa

Viewers also liked (20)

PDF
JPQL/ JPA Activity 1
 
PDF
JPQL/ JPA Activity 3
 
PPT
PPT
Web Services Part 2
ODP
How to bake reactive behavior into your Java EE applications
PDF
FinelyMe-JustFit Intro
PDF
Introduction to developing modern web apps
PDF
Continuous integration practices to improve the software quality
PDF
Quickstart for continuous integration
PPT
Java persistence api
PPTX
Spring 4. Part 1 - IoC, AOP
PDF
Gradle - Build System
ODP
Java Persistence API
PDF
20160523 hibernate persistence_framework_and_orm
PPTX
Spring Boot Update
PPTX
Cassandra for mission critical data
PDF
Java persistence api 2.1
PPTX
JPA For Beginner's
PDF
Second Level Cache in JPA Explained
PDF
DBM專案環境建置
JPQL/ JPA Activity 1
 
JPQL/ JPA Activity 3
 
Web Services Part 2
How to bake reactive behavior into your Java EE applications
FinelyMe-JustFit Intro
Introduction to developing modern web apps
Continuous integration practices to improve the software quality
Quickstart for continuous integration
Java persistence api
Spring 4. Part 1 - IoC, AOP
Gradle - Build System
Java Persistence API
20160523 hibernate persistence_framework_and_orm
Spring Boot Update
Cassandra for mission critical data
Java persistence api 2.1
JPA For Beginner's
Second Level Cache in JPA Explained
DBM專案環境建置
Ad

Similar to Introduction To Spring (20)

PDF
Clean code via dependency injection + guice
PPTX
Advanced #6 clean architecture
PDF
Test-driven serverless
PDF
Java EE 6 CDI Integrates with Spring & JSF
PDF
OSGi Community Event 2010 - Dependencies, dependencies, dependencies
PDF
Dev309 from asgard to zuul - netflix oss-final
PPTX
A brief overview of java frameworks
PDF
Dependencies, dependencies, dependencies
PDF
Dependency Injection in PHP
PDF
Asynchronous Programming at Netflix
PPTX
How to ensure Presto scalability 
in multi use case
PPTX
Mastering the Sling Rewriter by Justin Edelson
PPTX
Mastering the Sling Rewriter
PPTX
Movie Recommender System using Machine Learning
PDF
Dev ops journey basics and real life
PDF
End to-end testing from rookie to pro
PPTX
CloudStack Meetup Santa Clara
PDF
Developing maintainable Cordova applications
Clean code via dependency injection + guice
Advanced #6 clean architecture
Test-driven serverless
Java EE 6 CDI Integrates with Spring & JSF
OSGi Community Event 2010 - Dependencies, dependencies, dependencies
Dev309 from asgard to zuul - netflix oss-final
A brief overview of java frameworks
Dependencies, dependencies, dependencies
Dependency Injection in PHP
Asynchronous Programming at Netflix
How to ensure Presto scalability 
in multi use case
Mastering the Sling Rewriter by Justin Edelson
Mastering the Sling Rewriter
Movie Recommender System using Machine Learning
Dev ops journey basics and real life
End to-end testing from rookie to pro
CloudStack Meetup Santa Clara
Developing maintainable Cordova applications
Ad

More from Ilio Catallo (20)

PDF
C++ Standard Template Library
PDF
Regular types in C++
PDF
Resource wrappers in C++
PDF
Memory management in C++
PDF
Operator overloading in C++
PDF
Multidimensional arrays in C++
PDF
Arrays in C++
PDF
Pointers & References in C++
PDF
Spring MVC - Wiring the different layers
PDF
Java and Java platforms
PDF
Spring MVC - Web Forms
PDF
Spring MVC - The Basics
PDF
Web application architecture
PDF
Gestione della memoria in C++
PDF
Array in C++
PDF
Puntatori e Riferimenti
PDF
Java Persistence API
PDF
JSP Standard Tag Library
PDF
Internationalization in Jakarta Struts 1.3
PDF
Validation in Jakarta Struts 1.3
C++ Standard Template Library
Regular types in C++
Resource wrappers in C++
Memory management in C++
Operator overloading in C++
Multidimensional arrays in C++
Arrays in C++
Pointers & References in C++
Spring MVC - Wiring the different layers
Java and Java platforms
Spring MVC - Web Forms
Spring MVC - The Basics
Web application architecture
Gestione della memoria in C++
Array in C++
Puntatori e Riferimenti
Java Persistence API
JSP Standard Tag Library
Internationalization in Jakarta Struts 1.3
Validation in Jakarta Struts 1.3

Recently uploaded (20)

PDF
ANTIBIOTICS.pptx.pdf………………… xxxxxxxxxxxxx
PDF
2.FourierTransform-ShortQuestionswithAnswers.pdf
PDF
Sports Quiz easy sports quiz sports quiz
PPTX
IMMUNITY IMMUNITY refers to protection against infection, and the immune syst...
PDF
Microbial disease of the cardiovascular and lymphatic systems
PPTX
PPT- ENG7_QUARTER1_LESSON1_WEEK1. IMAGERY -DESCRIPTIONS pptx.pptx
PDF
The Lost Whites of Pakistan by Jahanzaib Mughal.pdf
PDF
Supply Chain Operations Speaking Notes -ICLT Program
PPTX
master seminar digital applications in india
PPTX
GDM (1) (1).pptx small presentation for students
PDF
Module 4: Burden of Disease Tutorial Slides S2 2025
PPTX
Cell Structure & Organelles in detailed.
PPTX
school management -TNTEU- B.Ed., Semester II Unit 1.pptx
PDF
VCE English Exam - Section C Student Revision Booklet
PDF
Saundersa Comprehensive Review for the NCLEX-RN Examination.pdf
PPTX
Cell Types and Its function , kingdom of life
PDF
O7-L3 Supply Chain Operations - ICLT Program
PPTX
PPH.pptx obstetrics and gynecology in nursing
PDF
Anesthesia in Laparoscopic Surgery in India
PDF
TR - Agricultural Crops Production NC III.pdf
ANTIBIOTICS.pptx.pdf………………… xxxxxxxxxxxxx
2.FourierTransform-ShortQuestionswithAnswers.pdf
Sports Quiz easy sports quiz sports quiz
IMMUNITY IMMUNITY refers to protection against infection, and the immune syst...
Microbial disease of the cardiovascular and lymphatic systems
PPT- ENG7_QUARTER1_LESSON1_WEEK1. IMAGERY -DESCRIPTIONS pptx.pptx
The Lost Whites of Pakistan by Jahanzaib Mughal.pdf
Supply Chain Operations Speaking Notes -ICLT Program
master seminar digital applications in india
GDM (1) (1).pptx small presentation for students
Module 4: Burden of Disease Tutorial Slides S2 2025
Cell Structure & Organelles in detailed.
school management -TNTEU- B.Ed., Semester II Unit 1.pptx
VCE English Exam - Section C Student Revision Booklet
Saundersa Comprehensive Review for the NCLEX-RN Examination.pdf
Cell Types and Its function , kingdom of life
O7-L3 Supply Chain Operations - ICLT Program
PPH.pptx obstetrics and gynecology in nursing
Anesthesia in Laparoscopic Surgery in India
TR - Agricultural Crops Production NC III.pdf

Introduction To Spring

  • 1. Introduc)on to Spring Ilio Catallo - info@iliocatallo.it
  • 2. Outline • What is Dependency Injec2on? • The Spring Framework • Wri2ng applica2ons in Spring • References
  • 3. What is Dependency Injec1on?
  • 4. Components Applica'ons typically consist of components that work together to form what the user sees as a coherent whole
  • 5. Movie rental Assume that we need to write a component that provides a list of movies directed by a par5cular director1 1 This use case is an adapta/on from the Mar/n Fowler's seminal example on Inversion of Control (see references)
  • 6. Movie rental Moreover, assume we are told that movies are currently being stored in a comma delimited file
  • 7. MovieService A"er much delibera/on, we delineate the following component, which we decide to call MovieService public class MovieService { private CSVMovieRepository repository; public List<Movie> moviesDirectedBy(String directorName) { ... } }
  • 8. MovieService Note that MovieService depends on CSVMovieRepository public class MovieService { private CSVMovieRepository repository; public List<Movie> moviesDirectedBy(String directorName) { ... } }
  • 9. CSVMovieRepository CSVMovieRepository is an addi'onal component that abstracts the comma delimited file containing the list of movies public class CSVMovieRepository { public CSVMovieRepository(String filename) { ... } public List<Movie> findAll() { ... } }
  • 10. The moviesDirectedBy use case An immediate implementa,on of moviesDirectedBy() is therefore as follows: public List<Movie> moviesDirectedBy(String directorName) { List<Movie> movies = repository.findAll(); Iterator<Movie> it = movies.iterator(); while (it.hasNext()) { Movie movie = it.next(); if (!movie.getDirector().equals(directorName)) it.remove(); } return movies; }
  • 11. The moviesDirectedBy use case Alterna(vely, we can use the Stream API in order to obtain a terser implementa(on public List<Movie> moviesDirectedBy(String directorName) { repository.findAll() .stream() .filter(m -> m.getDirector().equals(directorName)) .collect(Collectors.toList()); }
  • 12. MovieService class public class MovieService { private CSVMovieRepository repository; public MovieService() { this.repository = new CSVMovieRepository("movies.csv"); } public List<Movie> moviesDirectedBy(String directorName) { List<Movie> movies = repository.findAll(); Iterator<Movie> it = movies.iterator(); while (it.hasNext()) { Movie movie = it.next(); if (!movie.getDirector().equals(directorName)) it.remove(); } return movies; } }
  • 14. Unit tes(ng MovieService Assume that we now want to unit test MovieService public class MovieServiceTest { @Test public void moviesDirectedByTest() { ... } }
  • 15. Unit tes(ng MovieService We want to ensure the correctness of moviesDirectedBy() by checking its output against a set of controlled movies
  • 16. Unit tes(ng MovieService For instance, given the following data Sophia Coppola, Lost in Translation Christopher Nolan, Inception Christopher Nolan, The Dark Knight
  • 17. Unit tes(ng MovieService We want to test if moviesDirectedBy("Sophia Coppola") returns the expected output @Test public void moviesDirectedByTest() { List<Movie> movies = service.moviesDirectedBy("Shopia Coppola"); assertTrue(movies.length == 1); assertTrue(movies.get(0).getDirector().equals("Sophia Coppola")); assertTrue(movies.get(0).getTitle().equals("Lost in Translation")); }
  • 18. MockMovieRepository We can therefore devise a MockMovieRepository: public class MockMovieRepository { public List<Movie> findAll() { return Arrays.asList( new Movie("Sophia Coppola", "Lost in Translation"), new Movie("Christopher Nolan", "Inception"), new Movie("Christopher Nolan", "The Dark Knight") ); } }
  • 19. Unit tes(ng MovieService To use our test data, we need to replace CSVMovieRepository with MockMovieRepository
  • 20. Unit tes(ng MovieService We need to unplug MovieService from CSVMovieRepository
  • 21. Unit tes(ng MovieService However, there is no way to replace CSVMovieRepository with MockMovieRepository public class MovieService { private CSVMovieRepository repository; public MovieService() { this.repository = new CSVMovieRepository("movies.csv"); } }
  • 22. Unit tes(ng MovieService This is because MovieService instan-ates its own dependency public class MovieService { private CSVMovieRepository repository; public MovieService() { this.repository = new CSVMovieRepository("movies.csv"); } }
  • 23. MovieService cannot be tested Thus, we found out that our solu1on is not unit testable public class MovieService { private CSVMovieRepository repository; public MovieService() { this.repository = new CSVMovieRepository("movies.csv"); } }
  • 24. What could ever happen? ¯_( )_/¯
  • 25. What could ever happen?
  • 26. Variability Apart from testability, we may face an even bigger issue with our solu7on
  • 27. Variability Assume that we are suddenly been told that from now on movies are going to be stored in a rela%on database
  • 28. Variability That requires changing MovieService, even though the real change involves a different component public class MovieService { public SQLMovieRepository repository; public MovieService() { this.repository = new SQLMovieRepository(...); } ... }
  • 29. Obtaining the movie list This appears even more suspicious if we no2ce that the implementa2on of moviesDirectedBy() does not change public List<Movie> moviesDirectedBy(String directorName) { List<Movie> movies = repository.findAll(); ... }
  • 30. Obtaining the movie list As a ma&er of fact, MovieService does not need to know how the movies are stored public List<Movie> moviesDirectedBy(String directorName) { List<Movie> movies = repository.findAll(); ... }
  • 31. Obtaining the movie list There are many different ways of storing the movie list • Database • File system • Remote web service
  • 32. MovieRepository as an interface We can explicitly model this variability by defining a MovieRepository interface with a unique method public interface MovieRepository { List<Movie> findAll(); }
  • 33. MovieRepository as an interface Each MovieRepository implementa-on has its own way of retrieving the data public class SQLMovieRepository implements MovieRepository {...} public class CSVMovieRepository implements MovieRepository {...} public class RESTMovieRepository implements MovieRepository {...}
  • 34. External dependency Instead of le,ng MovieService look up the right implementa5on, we provide it as an external dependency public class MovieService { private MovieRepository repository; public MovieService(MovieRepository repository) { this.repository = repository; } ... }
  • 35. Composing objects We can now provide different implementa2ons of MovieRepository to MovieService public class MovieService { private MovieRepository repository; public MovieService(MovieRepository repository) { this.repository = repository; } ... }
  • 36. Composing objects This allows different developers to reuse the same components in different situa5ons public class MovieService { private MovieRepository repository; public MovieService(MovieRepository repository) { this.repository = repository; } ... }
  • 37. Dependency inversion principle What we did in the above is a direct applica3on of the dependency inversion principle
  • 38. Dependency inversion principle 1. High-level modules should not depend on low-level modules. Both should depend on abstrac:ons 2. Abstrac:ons should not depend upon details. Details should depend upon abstrac:ons
  • 39. Both should depend on abstrac1ons +--------------+ +-----------------+ | | | | | MovieService +----------> MovieRepository | | | | | +--------------+ +--------^--------+ | | | +---------+----------+ | | | SQLMovieRepository | | | +--------------------+
  • 40. Details should depend upon abstrac2ons
  • 41. Details should depend upon abstrac2ons +--------------------------------------------------+ | | | +--------------+ +-----------------+ | | | | | | | | | MovieService +----------> MovieRepository | | | | | | | | | +--------------+ +--------^--------+ | | | | +--------------------------------------------------+ | +---------+----------+ | | | SQLMovieRepository | | | +--------------------+
  • 42. Testability As a welcome byproduct, we gain the possibility of tes8ng MovieService @Test public void moviesDirectedByTest() { MovieService ms = new MovieService(new MockMovieRepository()); List<Movie> movies = ms.moviesDirectedBy("Sophia Coppola"); assertTrue(movies.length == 1); assertTrue(movies.get(0).getDirector().equals("Sophia Coppola")); assertTrue(movies.get(0).getTitle().equals("Lost in Translation")); }
  • 44. Deciding for a MovieRepository At a certain point we need to decide for a specific implementa-on of MovieRepository
  • 45. Factories To this end, we write a factory class, whose responsibility is to provide fully-constructed MovieService objects
  • 46. Factories For instance, we could devise the following simple factory2 public class MovieServiceFactory { public MovieService create(String type) { if (type.equals("CSV")) return new MovieService(new CSVMovieRepository(...)); if (type.equals("SQL")) ... return null; } } 2 Here, we are using the so called simple factory pa/ern. Although it is in turn sub-op9mal, we decided for this pa<ern because of the similarity of its interface with that of Spring's own factories
  • 47. Factories We can finally obtain a fully-constructed MovieService public static void main(String[] args) { ... MovieService service = factory.create("SQL"); List<Movie> movies = service.moviesDirectedBy("Sophia Coppola"); }
  • 48. Wiring objects Developers of the applica0on are in charge of wiring the different components together
  • 49. Wiring objects That is, developers are in control of the assembly phase of the applica5on components
  • 50. Wiring objects Developers would happily give up this control to someone else
  • 51. Wiring objects That is, developers would happily stop wri$ng factories
  • 52. Wiring objects We would like a 3rd -party factory to take care of crea0ng and wiring the different objects of the applica0on on our behalf MovieService movieService = externFactory.getComponent("SQL");
  • 53. Dependency Injec+on Dependency injec+on (DI) is a pa*ern whereby the responsibility of crea7ng and wiring applica7on objects is deferred to a 3rd -party factory
  • 54. Dependency Injec+on Namely, the 3rd -party factory will: • Instan'ate components • Provide dependencies to each component • Manage the lifecycle of each component
  • 56. The Spring framework Spring is a Java framework that provides comprehensive infrastructure support for developing Java applica6ons
  • 57. Spring DI Containers In Spring, applica-on components are instan&ated and managed directly by the framework
  • 58. Spring DI Containers Objects live within a dependency-inversion container +-------------------------------+ | +-------+ +-------+ | | | | | | | | | A +------> B | | | | | | | | | +---^---+ +---^---+ | | | | | | | | | | +---+---+ | | | | | | | | | C +----------+ | | | | | | +-------+ | +-------------------------------+ Spring DI container
  • 59. Spring DI Containers Such a DI container plays the role of the 3rd -party factory +-------------------------------+ | +-------+ +-------+ | | | | | | | | | A +------> B | | | | | | | | | +---^---+ +---^---+ | | | | | | | | | | +---+---+ | | | | | | | | | C +----------+ | | | | | | +-------+ | +-------------------------------+ Spring DI container
  • 60. Spring DI Containers It is responsible for instan&a&ng and assembling the objects +-------------------------------+ | +-------+ +-------+ | | | | | | | | | A +------> B | | | | | | | | | +---^---+ +---^---+ | | | | | | | | | | +---+---+ | | | | | | | | | C +----------+ | | | | | | +-------+ | +-------------------------------+ Spring DI container
  • 61. Spring beans A bean is an applica)on object that is instan)ated, and otherwise managed by a Spring DI container +-------------------------------+ | +-------+ +-------+ | | | | | | | | | A +------> B | | | | | | | | | +---^---+ +---^---+ | | | | | | | | | | +---+---+ | | | | | | | | | C +----------+ | | | | | | +-------+ | +-------------------------------+ Spring DI container
  • 62. Spring DI Containers Spring comes with two families of containers: • Containers that implement the BeanFactory interface • Containers that implement the ApplicationContext interface
  • 63. BeanFactory The BeanFactory interface provides basic support for DI
  • 64. ApplicationContext The ApplicationContext interface extends BeanFactory, providing addi4onal func4onali4es • Interna(onaliza(on support • The ability to load resource file
  • 65. Bean retrieving The ApplicationContext interface models a sophis2cated implementa2on of the factory pa*ern T getBean(String name, Class<T> requiredType)
  • 66. Bean retrieving By using the getBean() method, developers can retrieve instances of the applica7on beans T getBean(String name, Class<T> requiredType)
  • 67. Bean retrieving Example of bean retrieving: ApplicationContext c = new ClassPathXmlApplicationContext("ex1.xml"); MovieService movieService = c.getBean("SQL", MovieService.class);
  • 68. Bean retrieving ClassPathXmlApplicationContext is an implementa+on of ApplicationContext ApplicationContext c = new ClassPathXmlApplicationContext("ex1.xml"); MovieService movieService = c.getBean("SQL", MovieService.class);
  • 70. Configura)on metadata The container gets instruc/ons on what objects to instan/ate and configure by reading some configura)on metadata + Business objects | | | | +---------v---------+ | | | Spring | +-------------> Container | | | Configuration +---------+---------+ metadata | (e.g., XML file) | | v Fully configured system
  • 71. Configura)on metadata Through the configura.on metadata, the developer tells the Spring container how to assemble objects + Business objects | | | | +---------v---------+ | | | Spring | +-------------> Container | | | Configuration +---------+---------+ metadata | (e.g., XML file) | | v Fully configured system
  • 72. Configura)on metadata The configuring metadata can be represented in: • XML • Java annota,on • Java code
  • 73. Configura)on metadata The configura-on metadata ex1.xml is loaded from the CLASSPATH ApplicationContext c = new ClassPathXmlApplicationContext("ex1.xml"); MovieService movieService = c.getBean("SQL", MovieService.class);
  • 74. Dependencies vs. business logic The DI Container allows decoupling the specifica(on of dependencies from the actual program logic
  • 76. POJOs Many Java frameworks require developers to extend classes or implement interfaces provided by the framework itself public class MyServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response); public void doPost(HttpServletRequest request, HttpServletResponse response); public void init(); public void destroy(); }
  • 77. POJOs Spring beans are instead Plain Old Java Objects (POJOs) public class MovieService { private MovieRepository repository; public MovieService(MovieRepository repository) { this.repository = repository; } ... }
  • 78. POJOs Because of this, components in a Spring-based applica8on o9en have no indica(on that they are being used by Spring
  • 79. Movie rental Assume that we want to take advantage of the Spring framework for our movie rental applica.on
  • 80. Movie rental We need to instruct the Spring DI container about the dependency between MovieService and MovieRepository +--------------+ +-----------------+ | | | | | MovieService +----------> MovieRepository | | | | | +--------------+ +--------^--------+ | | | +---------+----------+ | | | SQLMovieRepository | | | +--------------------+
  • 81. Configuring the container We need to configure Spring to tell it what beans it should contain, and how to wire those beans +---------------------------------------------------+ | +--------------+ +-----------------+ | | | | | | | | | MovieService +----------> MovieRepository | | | | | | | | | +--------------+ +--------^--------+ | | | | | | | | | | | +---------+----------+ | | | | | | | SQLMovieRepository | | | | | | | +--------------------+ | +---------------------------------------------------+ Spring DI container
  • 82. Configuring the container For now, we will focus on tradi2onal XML configura-on
  • 83. The <beans> element The root element of the Spring configura4on file is the <beans> element <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/ spring-beans.xsd"> <!-- CONFIGURE APPLICATION BEANS HERE --> </beans>
  • 84. The <bean> element Each applica)on bean is associated with a <bean> element in the XML configura)on file <bean id="inMemoryMovieRepository” class="it.polimi.awt.repository.InMemoryMovieRepository"> ... </bean>
  • 85. The <bean> element Every bean has one (or more) id a0ribute, and a class a0ribute <bean id="inMemoryMovieRepository” class="it.polimi.awt.repository.InMemoryMovieRepository"> ... </bean>
  • 86. The <bean> element Namely: • If more iden,fiers are specified, the extra ones are considered as aliases • The class a8ribute could either specify the class of the bean to be constructed or the name of a sta,c factory method
  • 87. How to inject dependencies In Spring, dependencies are injected through: • Construc*on-based injec*on • Se4er-based injec*on • Arguments to a factory method
  • 88. Constructor-based injec1on Constructor-based injec1on is accomplished by the container invoking the bean constructor <bean id="movieService" class="it.polimi.awt.service.MovieService"> <constructor-arg ref="inMemoryMovieRepository"/> </bean>
  • 89. Constructor-based injec1on The <constructor-arg> element allows injec0ng a dependency through a constructor call <bean id="movieService" class="it.polimi.awt.spring.MovieService"> <constructor-arg ref="inMemoryMovieRepository"/> </bean>
  • 90. Se#er-based injec/on Se#er-based injec/on is accomplished by the container calling se3er methods on the bean3 <bean id="lostInTranslation" class="it.polimi.awt.domain.Movie"> <property name="title" value="Lost in Translation"/> <property name="director" value="Sophia Coppola"/> </bean> 3 As we will see, Movies are domain objects, which usually do not need injec5on. Here, we are doing this for the sole sake of presen5ng an example of se>er-based injec5on
  • 91. Se#er-based injec/on The <property> element injects the dependency by calling the property se5er <bean id="lostInTranslation" class="it.polimi.awt.domain.Movie"> <property name="title" value="Lost in Translation"/> <property name="director" value="Sophia Coppola"/> </bean>
  • 92. Constructor vs. se-ers As a rule of thumb, use constructor arguments for mandatory dependencies and se6ers for op*onal dependencies
  • 93. Spring beans vs. JavaBeans Despite the similar name, keep in mind that a DI container is not limited to JavaBeans4 and it can manage virtually any class 4 Recall that JavaBeans are objects with i) only a default constructor; and ii) appropriate ge<ers and se<ers
  • 97. References • Mar%n Fowler, Inversion of Control and Dependency Injec%on pa;ern • SpringSource, Spring Framework Reference • Craig Walls, Spring in Ac%on (3rd Edi%on), Manning Publica%ons