---
title: Spring Autowiring by Example
url: https://blog.octoperf.com/spring-autowiring-by-example/
date: '2018-02-08'
authors:
- jloisel
categories:
- Development
tags:
- Java
- Spring
- Maven
description: Learn how to autowire beans, inject dependencies into other beans and explore various autowiring methods with Spring. And make your code more extensible.
---

# Spring Autowiring by Example

[Spring](https://spring.io) is a **Java library** which delivers a useful feature: [Inversion Of Control](https://en.wikipedia.org/wiki/Inversion_of_control). Basically, instead of instantiating your Java services with `new`, **Spring does it for you**.

You may be wondering: 

- That's nice, but isn't **new** already enough?
- How does the `@Autowired` annotation work?
- How does Spring instantiated and lookup the right beans and services for me?

Good news! We've got you covered. **I know how difficult Spring is to understand, I've been there**. These **carefully crafted real-world examples** should speak to you.


When you application grows bigger and bigger, you usually create services and use them directly in your code via static methods like in the following:

```java

public class MyService {
  private static MyService instance = null;

  public void foo() {

  }

  public static MyService getInstance() {
    if (instance == null) {
      instance = new MyService();
    }
    return instance;
  }
}

// Code which uses the service

MyService.getInstance().foo();

```

While this approach is quite reasonable in a small program, it has numerous disadvantages:

- **Unit-Testing is difficult**: statically accessed resources are difficult to mock,
- **Maintainability**: code is tightly coupled to the services it uses.

So, how can Spring solve those issues? The answer is: **Autowiring**. Let's see how it works!

## Maven Dependencies

First, let's configure the Maven dependencies in our `pom.xml`:

```xml

<properties>
  <jackson.version>2.9.3</jackson.version>
  <spring.version>5.0.1.RELEASE</spring.version>
  <spring.boot.version>1.5.9.RELEASE</spring.version>
</properties>

<dependencies>
  <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>${jackson.version}</version>
  </dependency>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
    <version>${spring.boot.version}</version>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>${spring.version}</version>
  </dependency>
</dependencies>
```

In this example, we're going to use [Spring Boot](https://projects.spring.io/spring-boot/). 

## Bootstrapping via Spring

We need a bootstrap in our application with a `main` which delegates all the work to *Spring*:

```java

package com.octoperf;

@SpringBootApplication
public class Application {

  public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
  }
}

```

Basically, this tells Spring Boot to start the application by scanning all the classes under the `com.octoperf` package. For more information see the [SpringBootApplication documentation](https://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-using-springbootapplication-annotation.html).

## Service Interface

Great! Now we are going to create a service which wraps the Jackson `ObjectMapper`. The purpose is to hide the Jackson API from the rest of our code. This is called **hiding the implementation details**.

```java

package com.octoperf.tools.jackson.mapper;

import com.fasterxml.jackson.core.type.TypeReference;

import java.io.IOException;
import java.lang.reflect.Type;

public interface JsonMapperService {

  String toJson(Object instance) throws IOException;

  <T> T fromJson(String json, Class<T> clazz) throws IOException;
}

```

This service provides two methods:

- **serializing an object** instance to Json,
- and **deserializing a json** to an object instance.

I'm already hearing you asking: **Why do we need to define an interface? Can't we define the service directly?** And that's a good question!

There are multiple advantages of using an interface instead of a concrete class:

- **Decoupling**: instead of depending on the Jackson service here, we depend on an API agnostic service interface. The code which uses this service doesn't know it's being implemented with Jackson underneath,
- **Testability**: the code where the `JsonMapperService` is injected can be easily **mocked**. Interfaces are known to be easy to mock and work with.

Also, you may take a look at [Why Impl Classes are Evil](https://blog.octoperf.com/impl-classes-are-evil/) to better name your implementation classes.

## Service Implementation

Now, let's dive into the implementation which is pretty straight forward. The following example service illustrates the use of **constructor injection** (or **constructor autowiring**)

```java

package com.octoperf.tools.jackson.mapper;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.NamedType;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.lang.reflect.Type;
import java.util.Set;

import static com.google.common.base.Preconditions.checkNotNull;

@Service
final class JacksonJsonMapperService implements JsonMapperService {

  private final ObjectMapper mapper;

  JacksonJsonMapperService(final ObjectMapper mapper) {
    super();
    this.mapper = checkNotNull(mapper);
  }

  @Override
  public String toJson(final Object instance) throws IOException {
    return mapper.writeValueAsString(instance);
  }

  @Override
  public <T> T fromJson(final String json, final Class<T> clazz) throws IOException {
    return mapper.readValue(json, clazz);
  }
}

```

As you can see, there are some interesting points to review here:

- `@Service` annotation on `JacksonJsonMapperService`: it tells *Spring* this is a service, instantiate it,
- `JacksonJsonMapperService` constructor: it requires an `ObjectMapper`.

What does Spring then? It does the following:

* Discover `JacksonJsonMapperService` is annotated with `@Service` and decides to instantiate it,
* Lookup `ObjectMapper` in the Spring context and inject it in the constructor,
* Register `JacksonJsonMapperService` as an instance of `JsonMapperService`.

Spring does everything through [Java Reflection](https://www.oracle.com/technetwork/articles/java/javareflection-1536171.html). On a practical standpoint, it performs instantiation and injection through a generic code which is completely decoupled from your own code.

Why isn't there any `@Autowired` annotation? **As of Spring 4**, this annotation is not required anymore when performing **constructor autowiring**.

Most of the time, the service implementation should: 

- Have a **package-protected** class,
- Be in a **maven module separated from the interface**.

See [Separation of Concerns](https://blog.octoperf.com/impl-classes-are-evil/#separation-of-concerns) for more information.

## Field Autowiring

What about **Field Autowiring**? It would look like this:

```java

@Service
final class JacksonJsonMapperService implements JsonMapperService {

  @Autowired
  private ObjectMapper mapper;

  @Override
  public String toJson(final Object instance) throws IOException {
    return mapper.writeValueAsString(instance);
  }

  @Override
  public <T> T fromJson(final String json, final Class<T> clazz) throws IOException {
    return mapper.readValue(json, clazz);
  }
}

```

The code is obviously **more concise**. However, this kind of injection is discouraged because the `JacksonJsonMapperService` is then **mutable**. The reference to the `ObjectMapper` could be changed within the service code. 

Field autowiring may be useful if you experience **circular dependency** injection.

## Setter Autowiring

What about **Setter Autowiring**? Let's see this case too:

```java

@Service
final class JacksonJsonMapperService implements JsonMapperService {

  private ObjectMapper mapper;

  @Override
  public String toJson(final Object instance) throws IOException {
    return mapper.writeValueAsString(instance);
  }

  @Override
  public <T> T fromJson(final String json, final Class<T> clazz) throws IOException {
    return mapper.readValue(json, clazz);
  }

  @Autowired
  public void setMapper(final ObjectMapper mapper) {
    this.mapper = checkNotNull(mapper);
  }
}

```

While this approach perfectly works too, **it's not recommended** for the same reason as before: **prefer immutable instead of mutable** ones. 

Setter autowiring may be useful if you experience **circular dependencies**.

## Spring Java Configuration

Another approach is to use a separate **Spring Java Config** like this one:

```java

package com.octoperf.tools.jackson.mapper;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import javax.inject.Singleton;
import java.util.Set;

import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL;
import static com.fasterxml.jackson.databind.MapperFeature.SORT_PROPERTIES_ALPHABETICALLY;

@Module
@Configuration
public class JacksonConfig {
  
  @Bean
  @Primary
  ObjectMapper objectMapper() {
    final ObjectMapper mapper = new ObjectMapper();
    mapper.findAndRegisterModules();
    mapper.setSerializationInclusion(NON_NULL);
    mapper.enable(SORT_PROPERTIES_ALPHABETICALLY);
    return mapper;
  }

  @Bean
  static JsonMapperService jsonMapperService(final ObjectMapper mapper) {
    return new JacksonJsonMapperService(mapper);
  }
}

```

Let's decrypt what's done here:

- `JacksonConfig` defines methods annotated with `@Bean`: those methods provide new instances of different beans,
- `ObjectMapper` is defined as `@Primary` because Spring Boot already provides one, but we need our own.
- methods in Spring Java [Configuration](https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/annotation/Configuration.html) can be either static or instance bound.

By defining a `JacksonConfig`, we must remove the `@Service` annotation on the `JacksonJsonMapperService`. Don't use both or you will end up with Spring blowing at your face that 2 instances of your bean have been instantiated. (and Spring doesn't know which one to inject in services that require it)

## Optional Dependencies

Optional dependencies are dependencies which are not required when autowiring the services and/or beans. By default, Spring throws an exception when a service that should be autowired by the dependencies cannot be found:

```
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: 
No qualifying bean of type [com.fasterxml.jackson.databind.ObjectMapper] found for dependency: 
expected at least 1 bean which qualifies as autowire candidate for this dependency. 
Dependency annotations: 
{@org.springframework.beans.factory.annotation.Autowired(required=true)}

One solution could be to mark the dependency as **not required**:
```

```java

@Service
final class JacksonJsonMapperService implements JsonMapperService {

  @Autowired(required=false)
  private ObjectMapper mapper;

  @Override
  public String toJson(final Object instance) throws IOException {
    if (mapper != null) {
      return mapper.writeValueAsString(instance);
    }
    return null;
  }

  @Override
  public <T> T fromJson(final String json, final Class<T> clazz) throws IOException {
    if (mapper != null) {
      return mapper.readValue(json, clazz);
    }
    return null;
  }
}

```

While this is perfectly valid, this approach usually leads to **cluttered code**:

- What should we do when the dependency is not there?
- How should the code behave: throw an exception or *return null* instead?

Think twice when using optional dependencies. This is usually a bad practice and should be avoided.

## Using @Qualifier

The [@Qualifier](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/beans/factory/annotation/Qualifier.html) annotation can be useful in a situation where you need to differentiate instances of the same type / interface.

Let's see an example. 

```java

package com.octoperf.commons.eventbus.spring;

import com.google.common.eventbus.AsyncEventBus;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.SubscriberExceptionHandler;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.concurrent.Executors;

@Configuration
class EventBusConfig {

  @Bean(destroyMethod="shutdown")
  @ConditionalOnMissingBean
  ListeningExecutorService listeningExecutorService() {
    return MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(4));
  }

  @Bean
  EventBus syncEventBus() {
    return new EventBus();
  }

  @Bean
  AsyncEventBus asyncEventBus(final ListeningExecutorService executor) {
    return new AsyncEventBus(executor);
  }
}


```

As you see in the configuration above, there are two instances of `EventBus` being wired. Any attempt to autowire an `EventBus` without `@Qualifier` would lead to an exception thrown from Spring.

To overcome this, let's now see how the **implementation service** uses the `@Qualifier` annotation:

```java

package com.octoperf.commons.eventbus.spring;

import com.google.common.eventbus.AsyncEventBus;
import com.google.common.eventbus.EventBus;
import com.octoperf.commons.eventbus.api.EventBusService;
import lombok.NonNull;
import lombok.experimental.FieldDefaults;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import static java.util.Objects.requireNonNull;
import static lombok.AccessLevel.PRIVATE;

@Service
@FieldDefaults(level=PRIVATE, makeFinal=true)
final class EventBusOrchestrationService implements EventBusService {
  AsyncEventBus async;
  EventBus sync;

  EventBusOrchestrationService(
    @Qualifier("asyncEventBus") final AsyncEventBus async,
    @Qualifier("syncEventBus") final EventBus sync) {
    super();
    this.async = requireNonNull(async);
    this.sync = requireNonNull(sync);
  }

  @Override
  public void register(final Object listener) {
    async.register(listener);
    sync.register(listener);
  }

  @Override
  public void postEvent(final Object event) {
    async.post(event);
  }

  @Override
  public void syncPostEvent(final Object event) {
    sync.post(event);
  }

}

```

`@Qualifier` allows to make a distinction between the two instances. Any attempt to autowire `EventBusOrchestrationService` without qualifier would end up with the following exception:

```
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: 
Error creating bean with name 'eventBusOrchestrationService': 
Unsatisfied dependency expressed through constructor parameter 1; 
nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.google.common.eventbus.EventBus' available: 
expected single matching bean but found 2: syncEventBus,asyncEventBus
```

Please, be careful when using `@Qualifier`. It's quite dangerous because it can lead to nasty errors. It's generally a bad practice to require a qualifier: it requires the service which is autowired to know which implementations are available. `@Qualifier` **scope should be as narrow as possible**, like in the example above.

You can even create your own *Qualifier* derived from Spring's `@Qualifier` annotation:

```java

@Qualifier
@Target({
  ElementType.FIELD, ElementType.METHOD, ElementType.TYPE, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyQualifier {
     
    String value();
 
}

```

This could be a **good compromise**: provide your own qualifier annotations alongside your service interface. Developers who require your service will then be aware that multiple ones are available, and one must be chosen.

To finish, Spring is also capable of **disambiguation** by using bean names:

```java


@Service
@FieldDefaults(level=PRIVATE, makeFinal=true)
final class EventBusOrchestrationService implements EventBusService {
  AsyncEventBus async;
  EventBus sync;

  EventBusOrchestrationService(
    final AsyncEventBus asyncEventBus,
    final EventBus syncEventBus) {
    super();
    this.async = requireNonNull(asyncEventBus);
    this.sync = requireNonNull(syncEventBus);
  }

  @Override
  public void register(final Object listener) {
    async.register(listener);
    sync.register(listener);
  }

  @Override
  public void postEvent(final Object event) {
    async.post(event);
  }

  @Override
  public void syncPostEvent(final Object event) {
    sync.post(event);
  }

}

```

Remember the names of the methods in the `EventBusConfig` , `asyncEventBus()` and `syncEventBus()`. By reusing the name of those methods in the constructor parameters, Spring is capable of resolving the right beans to inject. You can try this unit-test if you want:

```java

package com.octoperf.commons.eventbus.spring;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import static org.junit.Assert.assertNotNull;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes={EventBusConfig.class, EventBusOrchestrationService.class})
public class EventBusOrchestrationSpringTest {
  
  @Autowired
  private EventBusOrchestrationService service;
  
  @Test
  public void shouldPostEvent() {
    assertNotNull(service);
  }
}

```

It runs Spring autowiring isolated within the maven module. The test succeeds when the service is properly instantiated and autowired.

## Collection Autowiring

This is one of the most powerful ways to use Spring to write **Extensible code** which follows the [Open/Closed Principle](https://en.wikipedia.org/wiki/Open/closed_principle). It's also known as **List autowiring** or **Autowire List of beans**.

Don't worry, let's see a concrete example!

We're going to improve our `JsonMapperService` to allow third party code to register type mappings.

```java
package com.octoperf.tools.jackson.mapper;

@FunctionalInterface
public interface JsonRegistrator {

  void register(JsonRegistry mapper);
}

```

A `JsonRegistrator` receives a `JsonRegistry` which can be used to register sub-types:

```java


@FunctionalInterface
public interface JsonRegistry {

  void registerSubtype(Class<?> clazz, String name);
}

```

Our `JacksonJsonMapperService` is then going to implement `JsonRegistry`:

```java

package com.octoperf.tools.jackson.mapper;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.NamedType;

import java.io.IOException;
import java.lang.reflect.Type;
import java.util.Set;

import static com.google.common.base.Preconditions.checkNotNull;

@Service
final class JacksonJsonMapperService implements JsonMapperService, JsonRegistry {

  private final ObjectMapper mapper;

  JacksonJsonMapperService(final ObjectMapper mapper, final Set<JsonRegistrator> registrators) {
    super();
    this.mapper = checkNotNull(mapper);
    for (final JsonRegistrator registrator : registrators) {
      registrator.register(this);
    }
  }

...

  @Override
  public void registerSubtype(final Class<?> clazz, final String name) {
    mapper.registerSubtypes(new NamedType(clazz, name));
  }
}


```

See how a `Set<JsonRegistrator>` is injected in the constructor? Spring automatically resolves and instantiates all `JsonRegistrator` instances before instantiating the `JacksonJsonMapperService` service. It packs them into a `Set` and provides it to the service.

It's a great way to implement the [Strategy Pattern](https://en.wikipedia.org/wiki/Strategy_pattern)! Here is an example `JsonRegistrator` implementation:

```java

package com.octoperf.workspace.entity;

import com.octoperf.tools.jackson.mapper.JsonRegistrator;
import com.octoperf.tools.jackson.mapper.JsonRegistry;
import org.springframework.stereotype.Component;

@Component
final class WorkspaceAccessRegistrator implements JsonRegistrator {

  @Override
  public void register(final JsonRegistry mapper) {
    mapper.registerSubtype(AdminAccess.class, "AdminAccess");
    mapper.registerSubtype(TesterAccess.class, "TesterAccess");
    mapper.registerSubtype(ViewerAccess.class, "ViewerAccess");
  }
}


```

See how **this makes your code extensible**? Developers used to modify your service to include their subtype mappings. Now, they can simply create a `JsonRegistrator` bean to do this. It's a powerful example of the **Open/Closed Principled** in action!

That's already the end of our tutorial! *Feel free to share your autowiring techniques using Spring!*
