Skip to main content
Chapter 14 of 18 · 4 sections

Spring: Dependency Injection and IoC

Compare constructor, setter, field, optional, Java-configured, and XML-configured injection.

Original chapter: Dependency Injection (DI) and Inversion of Control (IoC). The text and examples below are preserved from the historical source; read the corrections above before using them.

Section 14.1: Autowiring a dependency through Java configuration

Constructor injection through Java configuration can also utilize autowiring, such as:

Source example · PDF page 56
@Configuration
class AppConfig {
 @Bean
 public Bar bar() { return new Bar(); }

 @Bean
 public Foo foo(Bar bar) { return new Foo(bar); }
}

Section 14.2: Autowiring a dependency through XML configuration

Dependencies can be autowired when using the component scan feature of the Spring framework. For autowiring to work, the following XML configuration must be made:

Source example · PDF page 56
<context:annotation-config/>
<context:component-scan base-package="[base package]"/>

where, base-package is the fully-qualified Java package within which Spring should perform component scan.

Constructor injection

Dependencies can be injected through the class constructor as follows:

Source example · PDF page 56
@Component
class Bar { ... }

@Component
class Foo {
 private Bar bar;

 @Autowired
 public Foo(Bar bar) { this.bar = bar; }
}

Here, @Autowired is a Spring-specific annotation. Spring also supports JSR-299 to enable application portability to other Java-based dependency injection frameworks. This allows @Autowired to be replaced with @Inject as:

Source example · PDF page 56
@Component
class Foo {
 private Bar bar;

 @Inject
 public Foo(Bar bar) { this.bar = bar; }
}

Property injection

Dependencies can also be injected using setter methods as follows:

Source example · PDF page 57
@Component
class Foo {
 private Bar bar;

 @Autowired
 public void setBar(Bar bar) { this.bar = bar; }
}

Field injection

Autowiring also allows initializing fields within class instances directly, as follows:

Source example · PDF page 57
@Component
class Foo {
 @Autowired
 private Bar bar;
}

For Spring versions 4.1+ you can use Optional for optional dependencies.

Source example · PDF page 57
@Component
class Foo {

   @Autowired
   private Optional<Bar> bar;
}

The same approach can be used for constructor DI.

Source example · PDF page 57
@Component
class Foo {
   private Optional<Bar> bar;

   @Autowired
   Foo(Optional<Bar> bar) {
       this.bar = bar;
   }
}

Section 14.3: Injecting a dependency manually through XML configuration

Consider the following Java classes:

Source example · PDF page 57
class Foo {
 private Bar bar;

 public void foo() {
   bar.baz();
 }
}

As can be seen, the class Foo needs to call the method baz on an instance of another class Bar for its method foo to work successfully. Bar is said to be a dependency for Foo since Foo cannot work correctly without a Bar instance.

Constructor injection

When using XML configuration for Spring framework to define Spring-managed beans, a bean of type Foo can be configured as follows:

Source example · PDF page 58
<bean class="Foo">
 <constructor-arg>
   <bean class="Bar" />
 </constructor-arg>
</bean>

or, alternatively (more verbose):

Source example · PDF page 58
<bean id="bar" class="bar" />

<bean class="Foo">
 <constructor-arg ref="bar" />
</bean>

In both cases, Spring framework first creates an instance of Bar and injects it into an instance of Foo. This example assumes that the class Foo has a constructor that can take a Bar instance as a parameter, that is:

Source example · PDF page 58
class Foo {
 private Bar bar;

 public Foo(Bar bar) { this.bar = bar; }
}

This style is known as constructor injection because the dependency (Bar instance) is being injected into through the class constructor.

Property injection

Another option to inject the Bar dependency into Foo is:

Source example · PDF page 58
<bean class="Foo">
 <property name="bar">
   <bean class="Bar" />
 </property>
</bean>

or, alternatively (more verbose):

Source example · PDF page 58
<bean id="bar" class="bar" />

<bean class="Foo">
 <property name="bar" ref="bar" />
</bean>

This requires the Foo class to have a setter method that accepts a Bar instance, such as:

Source example · PDF page 59
class Foo {
 private Bar bar;

 public void setBar(Bar bar) { this.bar = bar; }
}

Section 14.4: Injecting a dependency manually through Java configuration

The same examples as shown above with XML configuration can be re-written with Java configuration as follows.

Constructor injection

Source example · PDF page 59
@Configuration
class AppConfig {
 @Bean
 public Bar bar() { return new Bar(); }

 @Bean
 public Foo foo() { return new Foo(bar()); }
}

Property injection

Source example · PDF page 59
@Configuration
class AppConfig {
 @Bean
 public Bar bar() { return new Bar(); }

 @Bean
 public Foo foo() {
   Foo foo = new Foo();
   foo.setBar(bar());

   return foo;
 }
}
Buy me a coffee
Daily Practice
0/0