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
T...
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 clas...
MovieService
Note that MovieService depends on CSVMovieRepository
public class MovieService {
private CSVMovieRepository r...
CSVMovieRepository
CSVMovieRepository is an addi'onal component that abstracts
the comma delimited file containing the list...
The moviesDirectedBy use case
An immediate implementa,on of moviesDirectedBy() is
therefore as follows:
public List<Movie>...
The moviesDirectedBy use case
Alterna(vely, we can use the Stream API in order to obtain a terser
implementa(on
public Lis...
MovieService class
public class MovieService {
private CSVMovieRepository repository;
public MovieService() {
this.reposit...
Job done?
Unit tes(ng MovieService
Assume that we now want to unit test MovieService
public class MovieServiceTest {
@Test
public vo...
Unit tes(ng MovieService
We want to ensure the correctness of moviesDirectedBy() by
checking its output against a set of c...
Unit tes(ng MovieService
For instance, given the following data
Sophia Coppola, Lost in Translation
Christopher Nolan, Inc...
Unit tes(ng MovieService
We want to test if moviesDirectedBy("Sophia Coppola")
returns the expected output
@Test
public vo...
MockMovieRepository
We can therefore devise a MockMovieRepository:
public class MockMovieRepository {
public List<Movie> f...
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 Movi...
Unit tes(ng MovieService
This is because MovieService instan-ates its own dependency
public class MovieService {
private C...
MovieService cannot be tested
Thus, we found out that our solu1on is not unit testable
public class MovieService {
private...
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 Mo...
Obtaining the movie list
This appears even more suspicious if we no2ce that the
implementa2on of moviesDirectedBy() does n...
Obtaining the movie list
As a ma&er of fact, MovieService does not need to know how
the movies are stored
public List<Movi...
Obtaining the movie list
There are many different ways of storing the movie list
• Database
• File system
• Remote web serv...
MovieRepository as an interface
We can explicitly model this variability by defining a
MovieRepository interface with a uni...
MovieRepository as an interface
Each MovieRepository implementa-on has its own way of
retrieving the data
public class SQL...
External dependency
Instead of le,ng MovieService look up the right
implementa5on, we provide it as an external dependency...
Composing objects
We can now provide different implementa2ons of
MovieRepository to MovieService
public class MovieService ...
Composing objects
This allows different developers to reuse the same components in
different situa5ons
public class MovieSer...
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...
Both should depend on abstrac1ons
+--------------+ +-----------------+
| | | |
| MovieService +----------> MovieRepository...
Details should depend upon abstrac2ons
Details should depend upon abstrac2ons
+--------------------------------------------------+
| |
| +--------------+ +------...
Testability
As a welcome byproduct, we gain the possibility of tes8ng
MovieService
@Test
public void moviesDirectedByTest(...
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 MovieServi...
Factories
We can finally obtain a fully-constructed MovieService
public static void main(String[] args) {
...
MovieService ...
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 applica0o...
Dependency Injec+on
Dependency injec+on (DI) is a pa*ern whereby the responsibility
of crea7ng and wiring applica7on objec...
Dependency Injec+on
Namely, the 3rd
-party factory will:
• Instan'ate components
• Provide dependencies to each component
...
The Spring framework
The Spring framework
Spring is a Java framework that provides comprehensive
infrastructure support for developing Java app...
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
+-------------------------------+
| +-------+ +-...
Spring DI Containers
Such a DI container plays the role of the 3rd
-party factory
+-------------------------------+
| +---...
Spring DI Containers
It is responsible for instan&a&ng and assembling the objects
+-------------------------------+
| +---...
Spring beans
A bean is an applica)on object that is instan)ated, and otherwise
managed by a Spring DI container
+---------...
Spring DI Containers
Spring comes with two families of containers:
• Containers that implement the BeanFactory interface
•...
BeanFactory
The BeanFactory interface provides basic support for DI
ApplicationContext
The ApplicationContext interface extends BeanFactory,
providing addi4onal func4onali4es
• Interna(onali...
Bean retrieving
The ApplicationContext interface models a sophis2cated
implementa2on of the factory pa*ern
T getBean(Strin...
Bean retrieving
By using the getBean() method, developers can retrieve
instances of the applica7on beans
T getBean(String ...
Bean retrieving
Example of bean retrieving:
ApplicationContext c = new ClassPathXmlApplicationContext("ex1.xml");
MovieSer...
Bean retrieving
ClassPathXmlApplicationContext is an implementa+on of
ApplicationContext
ApplicationContext c = new ClassP...
Configura)on metadata
The container gets instruc/ons on what objects to instan/ate and
configure by reading some configura)on...
Configura)on metadata
Through the configura.on metadata, the developer tells the Spring
container how to assemble objects
+ ...
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 ClassPathXml...
Dependencies vs. business logic
The DI Container allows decoupling the specifica(on of
dependencies from the actual program...
Wri$ng applica$ons with Spring
POJOs
Many Java frameworks require developers to extend classes or
implement interfaces provided by the framework itself
p...
POJOs
Spring beans are instead Plain Old Java Objects (POJOs)
public class MovieService {
private MovieRepository reposito...
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
+--...
Configuring the container
We need to configure Spring to tell it what beans it should contain,
and how to wire those beans
+...
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="UT...
The <bean> element
Each applica)on bean is associated with a <bean> element in the
XML configura)on file
<bean id="inMemoryM...
The <bean> element
Every bean has one (or more) id a0ribute, and a class a0ribute
<bean id="inMemoryMovieRepository”
class...
The <bean> element
Namely:
• If more iden,fiers are specified, the extra ones are considered as
aliases
• The class a8ribute...
How to inject dependencies
In Spring, dependencies are injected through:
• Construc*on-based injec*on
• Se4er-based injec*...
Constructor-based injec1on
Constructor-based injec1on is accomplished by the container
invoking the bean constructor
<bean...
Constructor-based injec1on
The <constructor-arg> element allows injec0ng a dependency
through a constructor call
<bean id=...
Se#er-based injec/on
Se#er-based injec/on is accomplished by the container calling
se3er methods on the bean3
<bean id="lo...
Se#er-based injec/on
The <property> element injects the dependency by calling the
property se5er
<bean id="lostInTranslati...
Constructor vs. se-ers
As a rule of thumb, use constructor arguments for mandatory
dependencies and se6ers for op*onal dep...
Spring beans vs. JavaBeans
Despite the similar name, keep in mind that a DI container is not
limited to JavaBeans4
and it ...
References
References
• Mar%n Fowler, Inversion of Control and Dependency Injec%on
pa;ern
• SpringSource, Spring Framework Reference
...
Introduction To Spring
Introduction To Spring
Introduction To Spring
Upcoming SlideShare
Loading in …5
×

Introduction To Spring

1,297 views

Published on

A gentle introduction to the concept of dependency injection and its usage when writing applications in Spring

Published in: Education
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,297
On SlideShare
0
From Embeds
0
Number of Embeds
22
Actions
Shares
0
Downloads
0
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Introduction To Spring

  1. 1. Introduc)on to Spring Ilio Catallo - info@iliocatallo.it
  2. 2. Outline • What is Dependency Injec2on? • The Spring Framework • Wri2ng applica2ons in Spring • References
  3. 3. What is Dependency Injec1on?
  4. 4. Components Applica'ons typically consist of components that work together to form what the user sees as a coherent whole
  5. 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. 6. Movie rental Moreover, assume we are told that movies are currently being stored in a comma delimited file
  7. 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. 8. MovieService Note that MovieService depends on CSVMovieRepository public class MovieService { private CSVMovieRepository repository; public List<Movie> moviesDirectedBy(String directorName) { ... } }
  9. 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. 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. 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. 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; } }
  13. 13. Job done?
  14. 14. Unit tes(ng MovieService Assume that we now want to unit test MovieService public class MovieServiceTest { @Test public void moviesDirectedByTest() { ... } }
  15. 15. Unit tes(ng MovieService We want to ensure the correctness of moviesDirectedBy() by checking its output against a set of controlled movies
  16. 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. 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. 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. 19. Unit tes(ng MovieService To use our test data, we need to replace CSVMovieRepository with MockMovieRepository
  20. 20. Unit tes(ng MovieService We need to unplug MovieService from CSVMovieRepository
  21. 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. 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. 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. 24. What could ever happen? ¯_( )_/¯
  25. 25. What could ever happen?
  26. 26. Variability Apart from testability, we may face an even bigger issue with our solu7on
  27. 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. 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. 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. 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. 31. Obtaining the movie list There are many different ways of storing the movie list • Database • File system • Remote web service
  32. 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. 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. 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. 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. 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. 37. Dependency inversion principle What we did in the above is a direct applica3on of the dependency inversion principle
  38. 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. 39. Both should depend on abstrac1ons +--------------+ +-----------------+ | | | | | MovieService +----------> MovieRepository | | | | | +--------------+ +--------^--------+ | | | +---------+----------+ | | | SQLMovieRepository | | | +--------------------+
  40. 40. Details should depend upon abstrac2ons
  41. 41. Details should depend upon abstrac2ons +--------------------------------------------------+ | | | +--------------+ +-----------------+ | | | | | | | | | MovieService +----------> MovieRepository | | | | | | | | | +--------------+ +--------^--------+ | | | | +--------------------------------------------------+ | +---------+----------+ | | | SQLMovieRepository | | | +--------------------+
  42. 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")); }
  43. 43. Job done?
  44. 44. Deciding for a MovieRepository At a certain point we need to decide for a specific implementa-on of MovieRepository
  45. 45. Factories To this end, we write a factory class, whose responsibility is to provide fully-constructed MovieService objects
  46. 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. 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. 48. Wiring objects Developers of the applica0on are in charge of wiring the different components together
  49. 49. Wiring objects That is, developers are in control of the assembly phase of the applica5on components
  50. 50. Wiring objects Developers would happily give up this control to someone else
  51. 51. Wiring objects That is, developers would happily stop wri$ng factories
  52. 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. 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. 54. Dependency Injec+on Namely, the 3rd -party factory will: • Instan'ate components • Provide dependencies to each component • Manage the lifecycle of each component
  55. 55. The Spring framework
  56. 56. The Spring framework Spring is a Java framework that provides comprehensive infrastructure support for developing Java applica6ons
  57. 57. Spring DI Containers In Spring, applica-on components are instan&ated and managed directly by the framework
  58. 58. Spring DI Containers Objects live within a dependency-inversion container +-------------------------------+ | +-------+ +-------+ | | | | | | | | | A +------> B | | | | | | | | | +---^---+ +---^---+ | | | | | | | | | | +---+---+ | | | | | | | | | C +----------+ | | | | | | +-------+ | +-------------------------------+ Spring DI container
  59. 59. Spring DI Containers Such a DI container plays the role of the 3rd -party factory +-------------------------------+ | +-------+ +-------+ | | | | | | | | | A +------> B | | | | | | | | | +---^---+ +---^---+ | | | | | | | | | | +---+---+ | | | | | | | | | C +----------+ | | | | | | +-------+ | +-------------------------------+ Spring DI container
  60. 60. Spring DI Containers It is responsible for instan&a&ng and assembling the objects +-------------------------------+ | +-------+ +-------+ | | | | | | | | | A +------> B | | | | | | | | | +---^---+ +---^---+ | | | | | | | | | | +---+---+ | | | | | | | | | C +----------+ | | | | | | +-------+ | +-------------------------------+ Spring DI container
  61. 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. 62. Spring DI Containers Spring comes with two families of containers: • Containers that implement the BeanFactory interface • Containers that implement the ApplicationContext interface
  63. 63. BeanFactory The BeanFactory interface provides basic support for DI
  64. 64. ApplicationContext The ApplicationContext interface extends BeanFactory, providing addi4onal func4onali4es • Interna(onaliza(on support • The ability to load resource file
  65. 65. Bean retrieving The ApplicationContext interface models a sophis2cated implementa2on of the factory pa*ern T getBean(String name, Class<T> requiredType)
  66. 66. Bean retrieving By using the getBean() method, developers can retrieve instances of the applica7on beans T getBean(String name, Class<T> requiredType)
  67. 67. Bean retrieving Example of bean retrieving: ApplicationContext c = new ClassPathXmlApplicationContext("ex1.xml"); MovieService movieService = c.getBean("SQL", MovieService.class);
  68. 68. Bean retrieving ClassPathXmlApplicationContext is an implementa+on of ApplicationContext ApplicationContext c = new ClassPathXmlApplicationContext("ex1.xml"); MovieService movieService = c.getBean("SQL", MovieService.class);
  69. 69. 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
  70. 70. 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
  71. 71. Configura)on metadata The configuring metadata can be represented in: • XML • Java annota,on • Java code
  72. 72. 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);
  73. 73. Dependencies vs. business logic The DI Container allows decoupling the specifica(on of dependencies from the actual program logic
  74. 74. Wri$ng applica$ons with Spring
  75. 75. 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(); }
  76. 76. POJOs Spring beans are instead Plain Old Java Objects (POJOs) public class MovieService { private MovieRepository repository; public MovieService(MovieRepository repository) { this.repository = repository; } ... }
  77. 77. POJOs Because of this, components in a Spring-based applica8on o9en have no indica(on that they are being used by Spring
  78. 78. Movie rental Assume that we want to take advantage of the Spring framework for our movie rental applica.on
  79. 79. Movie rental We need to instruct the Spring DI container about the dependency between MovieService and MovieRepository +--------------+ +-----------------+ | | | | | MovieService +----------> MovieRepository | | | | | +--------------+ +--------^--------+ | | | +---------+----------+ | | | SQLMovieRepository | | | +--------------------+
  80. 80. 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
  81. 81. Configuring the container For now, we will focus on tradi2onal XML configura-on
  82. 82. 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>
  83. 83. 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>
  84. 84. 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>
  85. 85. 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
  86. 86. How to inject dependencies In Spring, dependencies are injected through: • Construc*on-based injec*on • Se4er-based injec*on • Arguments to a factory method
  87. 87. 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>
  88. 88. 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>
  89. 89. 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
  90. 90. 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>
  91. 91. Constructor vs. se-ers As a rule of thumb, use constructor arguments for mandatory dependencies and se6ers for op*onal dependencies
  92. 92. 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
  93. 93. References
  94. 94. 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

×