---
title: Immutable Spring Service with Lombok
url: https://blog.octoperf.com/immutable-spring-service-with-lombok/
date: '2016-03-24'
authors:
- jloisel
categories:
- Development
tags:
- Java
- Lombok
- Spring
description: Learn how to create constructor injected spring services with lombok.
---

# Immutable Spring Service with Lombok

[Project Lombok](https://projectlombok.org/) is an amazing Java library which makes it possible to write very concise code. It's an incredibly powerful library which uses an annotation processor to generate code behind the scene.

## Why use lombok

Let me show you a very simple example:

```java
@Value
public class Person {
 String firstname;
 String lastname;
}
```


Is equivalent to the vanilla Java example:

```java
@Value
public final class Person {
 private final String firstname;
 private final String lastname;

 public Person(final String firstname, final String lastname) {
   this.firstname = firstname;
   this.lastname = lastname;
 }

 public String getFirstname() {
   return firstname;
 }

 public String getLastname() {
   return lastname;
 }

 public boolean equals(Object other) {
   ...
 }

 public int hashCode() {
   ...
 }
}
```

And I skipped the verbose *equals()* and *hashCode()* methods content. We are going to see that Lombok not only allows you to write more concise code, but also [immutable](https://docs.oracle.com/javase/tutorial/essential/concurrency/immutable.html) objects **without the pain of code verbosity**.

## Legacy Spring service

[Spring](https://spring.io/) is a collection of very powerful libraries. We are going to be interested in the most famous one: the [dependency injection](https://en.wikipedia.org/wiki/Dependency_injection) engine. How many times have you seen this:

```java
@Service
public class PersonServiceImpl implements PersonService {
 
 @Autowired
 private Repository<Person> repository;

 ...
}
```

I guess, you see this very often. Most developers inject dependencies inside *@Service* annotated classes using **field injection**. It's purely because the constructor is verbose to write, even if it can be automatically generated by your IDE.

There are numerous issues with this service.

### Wrong naming convention

The service is named **PersonServiceImpl** which is a wrong [class naming convention](https://stackoverflow.com/questions/2814805/java-interfaces-implementation-naming-convention). You all know the *List* interface from Java collections. Have you seen a **ListImpl** anywhere? No, you have [LinkedList](https://docs.oracle.com/javase/8/docs/api/java/util/LinkedList.html), [ArrayList](https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html) along with many others implementations.


### Shy code

The class should be **package protected**: implementations of service interfaces should never be visible publicly. This is to **discourage injecting the implementation** instead of the service interface in other services. Shy codes tries to expose as little as possible knowledge to the other developers. It relies on the [law of Demeter](https://en.wikipedia.org/wiki/Law_of_Demeter).


### Mutability

The service is not **immutable** although it should be. **Any method of the service can overwrite the injected repository**. Also, a method could be called on the service before the repository would be injected, which can lead to a weird [NullPointer](https://docs.oracle.com/javase/8/docs/api/java/lang/NullPointerException.html).

Immutable classes also have a special meaning for the JVM which is beyond the scope of this article.

## Lombokified Spring service

Thanks to Lombok, there is no reason to write field injected services anymore. Here is the same service with **constructor injection** and immutability:

```java
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.NonNull;
import lombok.experimental.FieldDefaults;

@Service
@AllArgsConstructor(access = PACKAGE)
@FieldDefaults(level = PRIVATE, makeFinal = true)
final class DatabasePersonService implements PersonService {
 @NonNull
 Repository<Person> repository;

 ...
}
```

You have now a fully immutable constructor injected service without the pain of writing [boiler-plate code](https://en.wikipedia.org/wiki/Boilerplate_code) yourself.

### Service

```java
@Service
```

This is the Spring service annotation. It instructs Spring that this class is a [Service](https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/stereotype/Service.html) which needs to be instantiated.


### FieldDefault

```java
@FieldDefaults(level = PRIVATE, makeFinal = true)
```

This annotation indicates that the class field are all **private final**. This makes the service immutable. Now that all fields must be initialized at construction time, we need to add an *Autowired* constructor with all the fields.


### AllArgsConstructor

```java
@AllArgsConstructor(access = PACKAGE)
```

This annotation generates a package-protected constructor.

## Code generation

Lombok generates code in the annotation processing phase during compilation which means there is no runtime overhead (like with [Reflection](https://docs.oracle.com/javase/tutorial/reflect/)).

## Conclusion

Some developers are reluctant to massively use annotations due to the *magic* done behind the scene. It's necessary to understand the code lombok generates, but there is nothing difficult there. Once you have tried *Lombok*, you can't go back. It removes so much **boiler plate code** it's well worth learning to use it.

Our entire backend code is written with Lombok from the beginning. It saved us from writing **thousands of lines of code** that can be safely generated. This is part of our **Automate everything you can** rule.
