59 lines
2.3 KiB
Plaintext
59 lines
2.3 KiB
Plaintext
== Why is this an issue?
|
|
|
|
Dependency injection frameworks such as Spring support dependency injection by using annotations such as `@Inject` and `@Autowired`.
|
|
These annotations can be used to inject beans via constructor, setter, and field injection.
|
|
|
|
Generally speaking, field injection is discouraged.
|
|
It allows the creation of objects in an invalid state and makes testing more difficult.
|
|
The dependencies are not explicit when instantiating a class that uses field injection.
|
|
|
|
In addition, field injection is not compatible with final fields.
|
|
Keeping dependencies immutable where possible makes the code easier to understand, easing development and maintenance.
|
|
|
|
Finally, because values are injected into fields after the object has been constructed, they cannot be used to initialize other non-injected fields inline.
|
|
|
|
This rule raises an issue when the `@Autowired` or `@Inject` annotations are used on a field.
|
|
|
|
== How to fix it
|
|
Use constructor injection instead.
|
|
|
|
By using constructor injection, the dependencies are explicit and must be passed during an object's construction.
|
|
This avoids the possibility of instantiating an object in an invalid state and makes types more testable.
|
|
Fields can be declared final, which makes the code easier to understand, as dependencies don't change after instantiation.
|
|
|
|
=== Code examples
|
|
|
|
==== Noncompliant code example
|
|
|
|
[source,text,diff-id=1,diff-type=noncompliant]
|
|
----
|
|
public class SomeService {
|
|
@Autowired
|
|
private SomeDependency someDependency; // Noncompliant
|
|
|
|
private String name = someDependency.getName(); // Will throw a NullPointerException
|
|
}
|
|
----
|
|
|
|
==== Compliant solution
|
|
|
|
[source,text,diff-id=1,diff-type=compliant]
|
|
----
|
|
public class SomeService {
|
|
private final SomeDependency someDependency;
|
|
private final String name;
|
|
|
|
@Autowired
|
|
public SomeService(SomeDependency someDependency) {
|
|
this.someDependency = someDependency;
|
|
name = someDependency.getName();
|
|
}
|
|
}
|
|
----
|
|
|
|
== Resources
|
|
=== Articles & blog posts
|
|
* Baeldung - https://www.baeldung.com/java-spring-field-injection-cons[Why Is Field Injection Not Recommended?]
|
|
* Baeldung - https://www.baeldung.com/constructor-injection-in-spring[Constructor Dependency Injection in Spring]
|
|
* Oliver Drotbohm - https://odrotbohm.de/2013/11/why-field-injection-is-evil/[Why field injection is evil]
|