Project Lombok 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:
|
|
Is equivalent to the vanilla Java example:
|
|
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 objects without the pain of code verbosity.
Legacy Spring service
Spring is a collection of very powerful libraries. We are going to be interested in the most famous one: the dependency injection engine. How many times have you seen this:
|
|
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. You all know the List interface from Java collections. Have you seen a ListImpl anywhere? No, you have LinkedList, ArrayList 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.
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.
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:
|
|
You have now a fully immutable constructor injected service without the pain of writing boiler-plate code yourself.
Service
|
|
This is the Spring service annotation. It instructs Spring that this class is a Service which needs to be instantiated.
FieldDefault
|
|
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
|
|
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).
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.
Hi Jérôme! How do create test for this service with constructor injection and immutability? Could you add sample with Mock or JUnit for example?
In reply to Oleg
Hi Oleg,
You simply create an instance of the service by using
new
when performing regular junits (with mocks). I’m not sure to understand what you find difficult here. Then, you mock all the dependencies.Otherwise, for tests running in a Spring container, you just have to create a mock Spring
@Config
like this in your test sources:Or you can even using Spring’s
@MockBean
right in your JUnit running with Spring. See Spring Testing for more information.