"@Autowired" Should Only Be Used on a Single Constructor
What is it?
In a Spring application, only one constructor should be annotated with @Autowired
in each component when the default required attribute is true, to prevent ambiguity during bean creation.
Why apply it?
Having multiple constructors annotated with @Autowired
without specifying required=false
can lead to ambiguity, errors during Spring's dependency injection process, and make your code harder to understand and maintain.
How to fix it?
Ensure that only one constructor is annotated with @Autowired
in a component with required=true
, or set required=false
for additional constructors that can be used when their dependencies are available.
Examples
Example 1:
Negative
This example shows a class with multiple constructors marked @Autowired
, which leads to ambiguity as Spring cannot determine which constructor to use when injecting dependencies.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class MyComponent {
private final MyService myService;
@Autowired
public MyComponent(MyService myService) {
this.myService = myService;
// ...
}
@Autowired // Noncompliant
public MyComponent(MyService myService, Integer i) {
this.myService = myService;
// Additional logic here
// ...
}
}
Example 2:
Positive
This example shows a class with only one constructor marked with @Autowired
, which allows Spring to inject dependencies properly without ambiguity.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class MyComponent {
private final MyService myService;
@Autowired
public MyComponent(MyService myService) {
this.myService = myService;
// ...
}
public MyComponent(MyService myService, Integer i) {
this.myService = myService;
// Additional logic here
// ...
}
}
Negative
Here, multiple constructors are marked with @Autowired
and none have required=false
, which leads to ambiguous dependency injection paths.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class MyComponent {
private final MyService myService;
private final String configValue;
@Autowired // Noncompliant
public MyComponent(MyService myService, String configValue) {
this.myService = myService;
this.configValue = configValue;
// Primary constructor logic
}
@Autowired // Noncompliant
public MyComponent(String configValue) {
this.myService = null;
this.configValue = configValue;
// Alternative constructor logic
}
}
Example 3:
Positive
In this example, only the primary constructor is marked with @Autowired
while others are left unannotated.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class MyComponent {
private final MyService myService;
private final String configValue;
@Autowired
public MyComponent(MyService myService, String configValue) {
this.myService = myService;
this.configValue = configValue;
// Primary constructor logic
}
public MyComponent(String configValue) {
this.myService = null;
this.configValue = configValue;
// Alternative constructor logic
}
}