Issue
I am very new to Spring Boot. I have created a repository, which looks like this:
public interface UserRepository extends CrudRepository<User, Long> {
List<User> findByEmail(String email);
User findById(long id);
}
user.java
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String email;
private String password;
private boolean verified;
protected User() {}
public User(String email, String password, boolean verified) {
this.email = email;
this.password = password;
this.verified = verified;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public boolean isVerified() {
return verified;
}
public void setVerified(boolean verified) {
this.verified = verified;
}
}
And now I want to inject the repository into my controller. This is how I tried it:
@RestController
public class Register {
@Autowired
private UserRepository userRepository;
@PostMapping("/register")
public User registerUser() {
return userRepository.save(new User("[email protected]", "password", true));
}
}
Is my approach correct? If so, then why do I get a warning on @Autowired
that says:
Field injection is not recommended
?
Solution
You are applying field injection into your controller layer. There is a more efficient way to do that but first, take a look at why field injection is not recommended.
Reasons
- you can not define your dependent components as final(immutable).
- you can not instantiate your components for test purposes.
- your application may lead to circular dependencies.
- your application is tightly coupled to your container.
There may be more reasons that you can search for them if you want. So now take a look at better ways to perform dependency injection.
Constructor Injection
This purpose is just to define your required dependencies as parameters to the class's constructor.
Let's say we have a class called A
@Component
Class A {}
Notice that we have to define our class as a Component so the container can use it later.
Now we want to inject class A
to class B
with constructor injection purpose.
Class B {
private final A a;
Public B(A a) {
this.a = a;
}
}
We successfully performed constructor injection instead of field injection.
There is another way to do dependency injection called setter injection which is useful for injecting optional dependent components.
That's it.
Answered By - Danial Eskandari
Answer Checked By - Willingham (JavaFixing Volunteer)