Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between @RequiredArgsConstructor(onConstructor = @__(@Inject)) and @RequiredArgsConstructor?

What is the difference between Lombok's

@RequiredArgsConstructor 

and

@RequiredArgsConstructor(onConstructor = @__(@Inject))

I know that RequiredArgsConstructor injects all the final dependencies in constructor only.

like image 323
rishabhjainps Avatar asked Sep 06 '19 13:09

rishabhjainps


4 Answers

@RequiredArgsConstructor
class MyClass {
  private final DependencyA a;
  private final DependencyB b;
}

will generate

public MyClass(DependencyA a, DependencyB b) {
  this.a = a;
  this.b = b;
}

while

@RequiredArgsConstructor(onConstructor = @__(@Inject))
class MyClass {
  private final DependencyA a;
  private final DependencyB b;
}

will generate

@Inject
public MyClass(DependencyA a, DependencyB b) {
  this.a = a;
  this.b = b;
}

From JDK 8 onwards, the syntax @RequiredArgsConstructor(onConstructor_ = {@Inject}) is also accepted.

I know RequiredArgsConstructor injects all the final dependencies.

All required dependencies, which include final and @NonNull fields.

like image 169
Andrew Tobilko Avatar answered Oct 19 '22 11:10

Andrew Tobilko


The second one will put the annotations you mention on the generated constructor.

For example, this: @RequiredArgsConstructor(onConstructor = @__(@Inject)) will generate a constructor annotated with @Inject

like image 40
Nir Levy Avatar answered Oct 19 '22 10:10

Nir Levy


The answers given have explained clearly what is the difference as asked by the OP. But i also feel that knowing why you would need @RequiredArgsConstructor(onConstructor = @__(@Inject)) instead of @RequiredArgsConstructor? is also important. If you are interested, read on...

In short, when Spring construct your beans (the classes annotated with @Component or related @Controller, @Service, @Repository - they all have @Component + extra functionality), Spring will need to look at the class constructor, to construct it. If you have only 1 constructor in your class, fine, no confusion, you only need @RequiredArgsConstructor.

What if you have 2 or more constructors? Which one does Spring use to construct your bean? Enter Lombok's @RequiredArgsConstructor(onConstructor = @__(@Inject)) or the more popular @RequiredArgsConstructor(onConstructor = @__(@Autowired)). As the annotation's attribute says, it puts @Autowired on the constructor to tell Spring to use that constructor at construction time.

That's it!

P.S I recommend this article if you want to read more about it.

like image 6
jumping_monkey Avatar answered Oct 19 '22 11:10

jumping_monkey


I will explain those annotations with simple examples

when to use @RequiredArgsConstructor

vanilla java

public class Item {
    private final String price;
    public Item(String price) {
        this.price=price;
    }
}

If you have a field or fields which is final (not null) then go with @RequiredArgsConstructor

lombok java

@RequiredArgsConstructor
public class Item {
    private final String price;
}

when to use @RequiredArgsConstructor(onConstructor = @__(@Inject))

vanilla java

public class Item {
    private final Shop shop;
    public Item(Shop shop) {
        this.shop=shop;
    }
}

If you have a field with your own type and bean instance is created in the configuration class. Then you can inject that bean instance to the shop filed of Item class using constructor injection with the help of @RequiredArgsConstructor(onConstructor = @__(@Inject))

But my recommendation is don't use @RequiredArgsConstructor(onConstructor = @__(@Inject)) when you are working with Spring. you can overcome it in 2 ways.

1.Using @Autowired Annotation

public class Item {
    private final Shop shop;
    @Autowired
    public Item(Shop shop) {
        this.shop=shop;
    }
}

2.Using @AllArgsConstructor Annotation

@AllArgsConstructor
public class Item {
    private final Shop shop;
}

I will add an extra point for someone's assist

when to use @AllArgsConstructor

vanilla java

public class Item {
    private String price;
    public Item(String price) {
        this.price=price;
    }
}

if you have a field or Fields which is not final (nullable) then go with @AllArgsConstructor.

lombok java

@AllArgsConstructor
public class Item {
    private String price;
}

Note

@AllArgsConstructor can be used with both final and non-final fields.

@RequiredArgsConstructor can not be used with the non-final field.

like image 1
NafazBenzema Avatar answered Oct 19 '22 10:10

NafazBenzema