Spring Boot 004: Lombok
Previous article: Spring Boot 003: Spring Boot Admin and GreenMail
Hey. I’ll be looking into some features of Lombok (Project Lombok) library. It’s focused on “Model Classes” mostly so there’s not much to code, just some use-cases. Try to have fun.
Prerequisites
Well, all you require is to have a model class but if you want to work on the same one that I work on ,you can simply get it by clicking here.

Lombok
By definition Project Lombok is a java library that automatically plugs into your editor and build tools, spicing up your java.
Never write another getter or equals method again, with one annotation your class has a fully featured builder, Automate your logging variables, and much more. I’ll try to show couple of features of it but in order to do that we’ll need implement Lombok into our project.
First of all we need to add Lombok dependency to pom.xml as below:
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.10</version>
</dependency>
And we need to add a plugin into our IDE so that it can work with lombok. So for the Intellij IDEA you can use this one or you can visit here for other IDE’s. We’re good to go after the installation.
Getter/Setter methods
Since Java 101 every one of us creating object/model classes with properties and getter/setter methods for these properties. It’s true that we’re not typing the methods since all the major IDE’s are capable of generating them for us(yay!) but Lombok brings out something much more useful. Let’s take look at the class below.
public class User {
private Long id;
private String name;
private String surname;
private Date birthDate;
public User(Long id, String name, String surname, Date birthDate) {
this.id = id;
this.name = name;
this.surname = surname;
this.birthDate = birthDate;
}
// long list of getters and setters
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public Date getBirthDate() {
return birthDate;
}
public void setBirthDate(Date birthDate) {
this.birthDate = birthDate;
}
}
And let’s implement Lombok via “@Getter,@Setter” annotations:
@Getter
@Setter
public class User {
private Long id;
private String name;
private String surname;
private Date birthDate;
public User(Long id, String name, String surname, Date birthDate) {
this.id = id;
this.name = name;
this.surname = surname;
this.birthDate = birthDate;
}
}
However you might want to use it for some of the properties as below:
public class User {
private Long id;
@Getter @Setter private String name;
private String surname;
private Date birthDate;
...
}
Or don’t generate a getter method for a specific property as below:
@Getter
@Setter
public class User {
@Getter(AccessLevel.NONE)
private Long id;
private String name;
private String surname;
private Date birthDate;
public User(Long id, String name, String surname, Date birthDate) {
this.id = id;
this.name = name;
this.surname = surname;
this.birthDate = birthDate;
}
}
Constructor methods
Well if you have model you’ll be using at least one constructor method. It can have all/some/none of the properties of class. Good thing is Lombok is providing us couple of options as such:
- NoArgsConstructor
- RequiredArgsConstructor
- AllArgsConstructor
So we can just have this:
@Getter
@Setter
@AllArgsConstructor
public class User {
private Long id;
private String name;
private String surname;
private Date birthDate;
}
Builder
Well, Lombok has another annotation called Builder. Since Java is not supporting default parameters* having a Model Builder might come in handy. See the example below for implementation:
@Getter
@Setter
@AllArgsConstructor
@Builder
public class User {
private Long id;
private String name;
private String surname;
private Date birthDate;
}
And you can just call it as this:
return User.builder().name(faker.name().firstName()).surname(faker.name()
.lastName()).build();// return new User(id, faker.name().firstName(), faker.name().lastName(),
*Default parameter is a functionality in couple of programming languages like Swift,Kotlin that you can just give default value to parameter in a function so you don’t have to give it a value like null while calling it. Check it out Swift implementation by clicking here.
Data
Lombok provides an annotation that brings out the following ones together:
- ToString
- EqualsAndHashCode
- Getter
- Setter
- RequiredArgsConstructor
@Data
@Builder
public class User {
private Long id;
private String name;
private String surname;
private Date birthDate;
}
Cleanup
Cleanup annotation helps us by calling the close method on the given variable after leaving the scope that variable’s in. Let’s have look at the code below:
private void streamWithoutCleanup(String[] args) throws Exception {
InputStream in = new FileInputStream(args[0]);
try {
OutputStream out = new FileOutputStream(args[1]);
try {
byte[] b = new byte[10000];
while (true) {
int r = in.read(b);
if (r == -1) break;
out.write(b, 0, r);
}
} finally {
if (out != null) {
out.close();
}
}
} finally {
if (in != null) {
in.close();
}
}
}
And the one with the Lombok:
private void streamWithCleanup(String[] args) throws Exception {
@Cleanup InputStream in = new FileInputStream(args[0]);
@Cleanup OutputStream out = new FileOutputStream(args[1]);
byte[] b = new byte[10000];
while (true) {
int r = in.read(b);
if (r == -1) break;
out.write(b, 0, r);
}
}
However you don’t really need to rely on Lombok here. You can just benefit plain Java’s try-with-resources as such:
private void streamWithoutCleanup(String[] args) throws Exception {
try (InputStream in = new FileInputStream(args[0])) {
try (OutputStream out = new FileOutputStream(args[1])) {
byte[] b = new byte[10000];
while (true) {
int r = in.read(b);
if (r == -1)
break;
out.write(b, 0, r);
}
}
}
}
At this point it’s developer’s choice to use Lombok’s way or Java’s. But with the Lombok you can declare Cleanup annotation on an object that doesn’t have “close() method” and you can call another method that doesn’t take any arguments as such:
@Cleanup("dispose") org.eclipse.swt.widgets.CoolBar bar = new CoolBar(parent, 0);
Log
Well, your code needs to have a Logging system in it. There lots of way of implementing but at the end we’re creating a Logger object by passing the current class as parameter in our classes and use it in them. Lombok has something that you’ll find useful:
@Log4j/*Creates private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(LogExample.class);*/@Slf4j/*Creates private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogExample.class);*//*Full list of loggers at: https://projectlombok.org/features/log*/
You can change com.tahaburak.atem.service.impl.DummyService.java as below to test it out:
@Slf4j
@Service
public class DummyService implements IDummyService {
private Faker faker;
@PostConstruct
private void fill() {
this.faker = generateFaker();
}
private Faker generateFaker() {
return new Faker(new Locale("en-US"));
}
@Override
public User getDummyUserById(Long id) {
log.info("generating the dummy user with id: " + id);
return User.builder().name(faker.name().firstName())
.surname(faker.name().lastName()).build();
}
}
Run the app and the visit http://localhost:2836/user/id/7 to see the log:
2020-01-12 22:57:53.814 INFO 16883 --- [nio-2836-exec-1] c.t.atem.service.impl.DummyService :
generating the dummy user with id: 7
Conclusion
Well, for some features of Lombok you might think “do I really need to add a library into the project just for this?”. However I believe if your project have or will have more than 10 classes having Lombok in it saves you from lots of legwork (it may not be the right discourse in our industry but you get the point). Even playing with it is fun.
Anyways, you can find the full code at Github.
Sincerely,
Burak.