ZEMOSO ENGINEERING STUDIO
June 5, 2022
5 min read

When not to @Autowire in Spring or Spring Boot applications

The above cartoon is a pretty common occurrence in most engineering and developer teams. Think about it this way: when we build products for our clients, we pay as much attention to what we should not be doing as we do to what we should be doing to create smart, future proofed products.

Besides, in most engineering problems, not paying attention to the “why” can lead to catastrophic codes.

But let’s get straight to the topic, dive deep into the different types of dependency injections for context before we discuss when and why we use one.

Types of dependency injection

1. Field injection

2. Constructor injection

3. Setter injection

Field injection

Simply put, spring will assign the dependencies directly to the fields, declaring a variable, hopefully private, and then annotating it with @Autowired.

Constructor injection

It’s when you statically define the list of required dependencies by articulating them to the class' constructor. You can let the spring container inject ‌dependencies directly through the constructor with @RestController.

Setter injection — rarely used

It is similar to field injection but the setter is annotated with @Autowired tag. It is the kind of injection where the spring framework uses the setter method to inject the dependency.

How do they differ?

 1. Field injection uses reflection to set the values of private variables.

 2. Constructor injection happens at the time of creating the object itself (and typically all the parameters are well-known).

 3. Setter injection uses setters to set the value.

Types of dependency injection

What’s the verdict?

Constructor injection is always the first choice when it comes to deploying a dependency injection because it’s reliable and strict.

Reliability: Constructor injection is the most reliable of the three because of immutable variables.

Maintainability: Constructor injection helps to identify the list of dependencies and makes the code more readable. In field and setter injections, autowired fields can mix up with regular fields, and therefore make it difficult to track the dependencies of the class. 

Testability: In construction injection, it is easy to mock dependencies as they can be passed and removed using the constructor, even without creating Spring Context that enables faster and cleaner tests. While using setter injection, it is easy to mock as mock objects can be set directly. However, it is most challenging to create mock beans for field injections as the shuffling between mock and actual beans is tedious. 

Consistency: Constructor injection is most consistent as the whole application uses similar coding and injection patterns. Setter and field injections are less consistent as they can be included anywhere in the code. 

Flexibility: Constructor offers the least amount of flexibility as it imposes strict design rules in the code. For setter and field injections, developers can easily add new dependencies, making them more flexible. 

Ease of code reviews: When you add a new dependency in constructor injection, developers have to update the constructors in multiple places so that reviewers can easily detect the breaking changes. When using field and setter injections, dependencies are added as a simple field, so reviewers might not even notice them. 

Modification of code: In setter and field injections, developers have the freedom to add unlimited new dependencies. Constructor injection is more aligned to the Open-Closed principle of SOLID principles. Any modification to the code for an extension or adding a new feature can be debated, which keeps the overall code cleaner. 

Cyclic dependency detection: Cyclic dependencies can be easily detected and fixed in constructor injection, while they are not detected at all in field and setter injections. 

Performance: For setter and field injections, each object can be created independently and dependencies are injected later on using reflection, thereby enabling faster launches. However, for constructor injection, beans have to be created in the correct order of dependencies, which increases the time taken to launch the application but ensures that developers have thought their structure through. 

Field injections are ideal for scenarios when constructor injection is absolutely unfeasible and circular dependencies have to be avoided, even if it is a work around. 

Other considerations

Somethings we consider when deciding between field injection and constructor injection are required and optional dependencies.

 1. While many argue that we can use field injection for optional and constructor injection for required dependencies, having optional dependency seems to be already reflective of bad design in most of the  cases; it might be worth taking another look at the design itself.

 2. Since the scope of an optional dependency is unrestricted, developers can add multiple dependencies by calling it optional, and reduce the quality @ of the overall code.

At Zemoso Labs, we follow the best design and coding principles, ensuring the highest quality of applications every time. This includes rigorous debate within our team members to identify the best possible solution. To learn more about our product engineering solutions, contact us today.

A version of this blog post was earlier published on Medium.

ZEMOSO ENGINEERING STUDIO

When not to @Autowire in Spring or Spring Boot applications

By Zemoso Engineering Studio
May 1, 2021
5 min read

The above cartoon is a pretty common occurrence in most engineering and developer teams. Think about it this way: when we build products for our clients, we pay as much attention to what we should not be doing as we do to what we should be doing to create smart, future proofed products.

Besides, in most engineering problems, not paying attention to the “why” can lead to catastrophic codes.

But let’s get straight to the topic, dive deep into the different types of dependency injections for context before we discuss when and why we use one.

Types of dependency injection

1. Field injection

2. Constructor injection

3. Setter injection

Field injection

Simply put, spring will assign the dependencies directly to the fields, declaring a variable, hopefully private, and then annotating it with @Autowired.

Constructor injection

It’s when you statically define the list of required dependencies by articulating them to the class' constructor. You can let the spring container inject ‌dependencies directly through the constructor with @RestController.

Setter injection — rarely used

It is similar to field injection but the setter is annotated with @Autowired tag. It is the kind of injection where the spring framework uses the setter method to inject the dependency.

How do they differ?

 1. Field injection uses reflection to set the values of private variables.

 2. Constructor injection happens at the time of creating the object itself (and typically all the parameters are well-known).

 3. Setter injection uses setters to set the value.

Types of dependency injection

What’s the verdict?

Constructor injection is always the first choice when it comes to deploying a dependency injection because it’s reliable and strict.

Reliability: Constructor injection is the most reliable of the three because of immutable variables.

Maintainability: Constructor injection helps to identify the list of dependencies and makes the code more readable. In field and setter injections, autowired fields can mix up with regular fields, and therefore make it difficult to track the dependencies of the class. 

Testability: In construction injection, it is easy to mock dependencies as they can be passed and removed using the constructor, even without creating Spring Context that enables faster and cleaner tests. While using setter injection, it is easy to mock as mock objects can be set directly. However, it is most challenging to create mock beans for field injections as the shuffling between mock and actual beans is tedious. 

Consistency: Constructor injection is most consistent as the whole application uses similar coding and injection patterns. Setter and field injections are less consistent as they can be included anywhere in the code. 

Flexibility: Constructor offers the least amount of flexibility as it imposes strict design rules in the code. For setter and field injections, developers can easily add new dependencies, making them more flexible. 

Ease of code reviews: When you add a new dependency in constructor injection, developers have to update the constructors in multiple places so that reviewers can easily detect the breaking changes. When using field and setter injections, dependencies are added as a simple field, so reviewers might not even notice them. 

Modification of code: In setter and field injections, developers have the freedom to add unlimited new dependencies. Constructor injection is more aligned to the Open-Closed principle of SOLID principles. Any modification to the code for an extension or adding a new feature can be debated, which keeps the overall code cleaner. 

Cyclic dependency detection: Cyclic dependencies can be easily detected and fixed in constructor injection, while they are not detected at all in field and setter injections. 

Performance: For setter and field injections, each object can be created independently and dependencies are injected later on using reflection, thereby enabling faster launches. However, for constructor injection, beans have to be created in the correct order of dependencies, which increases the time taken to launch the application but ensures that developers have thought their structure through. 

Field injections are ideal for scenarios when constructor injection is absolutely unfeasible and circular dependencies have to be avoided, even if it is a work around. 

Other considerations

Somethings we consider when deciding between field injection and constructor injection are required and optional dependencies.

 1. While many argue that we can use field injection for optional and constructor injection for required dependencies, having optional dependency seems to be already reflective of bad design in most of the  cases; it might be worth taking another look at the design itself.

 2. Since the scope of an optional dependency is unrestricted, developers can add multiple dependencies by calling it optional, and reduce the quality @ of the overall code.

At Zemoso Labs, we follow the best design and coding principles, ensuring the highest quality of applications every time. This includes rigorous debate within our team members to identify the best possible solution. To learn more about our product engineering solutions, contact us today.

A version of this blog post was earlier published on Medium.

Recent Publications
How to remix Amazon’s Working Backwards with Google’s Venture’s User Journey: The Dr. Strange Way
How to remix Amazon’s Working Backwards with Google’s Venture’s User Journey: The Dr. Strange Way
June 14, 2022
How we built a big data platform for a futuristic AgriTech product
How we built a big data platform for a futuristic AgriTech product
June 3, 2022
Zemoso Labs starts operations in Waterloo, Canada
Zemoso Labs starts operations in Waterloo, Canada
May 25, 2022
Deconstructing Elon Musk’s dog ate my homework answer for Twitter: More validation will be asked of startups
Deconstructing Elon Musk’s dog ate my homework answer for Twitter: More validation will be asked of startups
May 20, 2022
Real Talk: Lessons learned and evolved from 3M and Post-it®’s adoption of Crazy 8 methodology
Real Talk: Lessons learned and evolved from 3M and Post-it®’s adoption of Crazy 8 methodology
April 10, 2022
Why Realm trumps SQLite as database of choice for complex mobile apps — Part 1
Why Realm trumps SQLite as database of choice for complex mobile apps — Part 1
February 7, 2022
Understanding dynamic multi-column search with JPA Criteria for product development
Understanding dynamic multi-column search with JPA Criteria for product development
January 2, 2022
Product engineering zeitgeist: Implement OOPs in React JS using atomic design
Product engineering zeitgeist: Implement OOPs in React JS using atomic design
July 8, 2021
Honorable mention at O’Reilly’s Architectural Katas event
Honorable mention at O’Reilly’s Architectural Katas event
May 17, 2021
Product dev with testable spring boot applications, from day one
Product dev with testable spring boot applications, from day one
May 4, 2021
Efficiently handle data and integrations in Spring Boot
Efficiently handle data and integrations in Spring Boot
January 24, 2021
Unlock the power of atomic design in React and React Native using a theming library — Part 1
Unlock the power of atomic design in React and React Native using a theming library — Part 1
November 2, 2020
Our favorite CI/CD DevOps Practice: Simplify with GitHub Actions
Our favorite CI/CD DevOps Practice: Simplify with GitHub Actions
October 25, 2020
Kubernetes — What is it, what problems does it solve, and how does it compare with alternatives?
Kubernetes — What is it, what problems does it solve, and how does it compare with alternatives?
June 21, 2019
GraphQL — Why is it essential for agile product development?
GraphQL — Why is it essential for agile product development?
April 30, 2019
Orchestrating backend services for product development with AWS Step Functions
Orchestrating backend services for product development with AWS Step Functions
April 1, 2019
How To Decide When to Use Amazon Working Backwards, Business Model Canvas and Lean Canvas
How To Decide When to Use Amazon Working Backwards, Business Model Canvas and Lean Canvas
November 30, 2018
How to validate your Innovation: Mastering Experiment Design
How to validate your Innovation: Mastering Experiment Design
November 22, 2018
Working Backwards: Amazon's Culture of Innovation: My notes
Working Backwards: Amazon's Culture of Innovation: My notes
November 19, 2018
Product developer POV: Caveats when building with Spark
Product developer POV: Caveats when building with Spark
November 5, 2018
ZEMOSO ENGINEERING STUDIO
May 1, 2021
5 min read

When not to @Autowire in Spring or Spring Boot applications

The above cartoon is a pretty common occurrence in most engineering and developer teams. Think about it this way: when we build products for our clients, we pay as much attention to what we should not be doing as we do to what we should be doing to create smart, future proofed products.

Besides, in most engineering problems, not paying attention to the “why” can lead to catastrophic codes.

But let’s get straight to the topic, dive deep into the different types of dependency injections for context before we discuss when and why we use one.

Types of dependency injection

1. Field injection

2. Constructor injection

3. Setter injection

Field injection

Simply put, spring will assign the dependencies directly to the fields, declaring a variable, hopefully private, and then annotating it with @Autowired.

Constructor injection

It’s when you statically define the list of required dependencies by articulating them to the class' constructor. You can let the spring container inject ‌dependencies directly through the constructor with @RestController.

Setter injection — rarely used

It is similar to field injection but the setter is annotated with @Autowired tag. It is the kind of injection where the spring framework uses the setter method to inject the dependency.

How do they differ?

 1. Field injection uses reflection to set the values of private variables.

 2. Constructor injection happens at the time of creating the object itself (and typically all the parameters are well-known).

 3. Setter injection uses setters to set the value.

Types of dependency injection

What’s the verdict?

Constructor injection is always the first choice when it comes to deploying a dependency injection because it’s reliable and strict.

Reliability: Constructor injection is the most reliable of the three because of immutable variables.

Maintainability: Constructor injection helps to identify the list of dependencies and makes the code more readable. In field and setter injections, autowired fields can mix up with regular fields, and therefore make it difficult to track the dependencies of the class. 

Testability: In construction injection, it is easy to mock dependencies as they can be passed and removed using the constructor, even without creating Spring Context that enables faster and cleaner tests. While using setter injection, it is easy to mock as mock objects can be set directly. However, it is most challenging to create mock beans for field injections as the shuffling between mock and actual beans is tedious. 

Consistency: Constructor injection is most consistent as the whole application uses similar coding and injection patterns. Setter and field injections are less consistent as they can be included anywhere in the code. 

Flexibility: Constructor offers the least amount of flexibility as it imposes strict design rules in the code. For setter and field injections, developers can easily add new dependencies, making them more flexible. 

Ease of code reviews: When you add a new dependency in constructor injection, developers have to update the constructors in multiple places so that reviewers can easily detect the breaking changes. When using field and setter injections, dependencies are added as a simple field, so reviewers might not even notice them. 

Modification of code: In setter and field injections, developers have the freedom to add unlimited new dependencies. Constructor injection is more aligned to the Open-Closed principle of SOLID principles. Any modification to the code for an extension or adding a new feature can be debated, which keeps the overall code cleaner. 

Cyclic dependency detection: Cyclic dependencies can be easily detected and fixed in constructor injection, while they are not detected at all in field and setter injections. 

Performance: For setter and field injections, each object can be created independently and dependencies are injected later on using reflection, thereby enabling faster launches. However, for constructor injection, beans have to be created in the correct order of dependencies, which increases the time taken to launch the application but ensures that developers have thought their structure through. 

Field injections are ideal for scenarios when constructor injection is absolutely unfeasible and circular dependencies have to be avoided, even if it is a work around. 

Other considerations

Somethings we consider when deciding between field injection and constructor injection are required and optional dependencies.

 1. While many argue that we can use field injection for optional and constructor injection for required dependencies, having optional dependency seems to be already reflective of bad design in most of the  cases; it might be worth taking another look at the design itself.

 2. Since the scope of an optional dependency is unrestricted, developers can add multiple dependencies by calling it optional, and reduce the quality @ of the overall code.

At Zemoso Labs, we follow the best design and coding principles, ensuring the highest quality of applications every time. This includes rigorous debate within our team members to identify the best possible solution. To learn more about our product engineering solutions, contact us today.

A version of this blog post was earlier published on Medium.

Recent Publications

ZEMOSO ENGINEERING STUDIO

How we built a big data platform for a futuristic AgriTech product

June 3, 2022
8 min read
ZEMOSO NEWS

Zemoso Labs starts operations in Waterloo, Canada

May 25, 2022
5 min read
ZEMOSO ENGINEERING STUDIO

Honorable mention at O’Reilly’s Architectural Katas event

May 17, 2021
5 min read
ZEMOSO ENGINEERING STUDIO

Product dev with testable spring boot applications, from day one

May 4, 2021
5 min read
ZEMOSO ENGINEERING STUDIO

Efficiently handle data and integrations in Spring Boot

January 24, 2021
5 min read
ZEMOSO ENGINEERING STUDIO

Our favorite CI/CD DevOps Practice: Simplify with GitHub Actions

October 25, 2020
5 min read
ZEMOSO ENGINEERING STUDIO

GraphQL — Why is it essential for agile product development?

April 30, 2019
12 min read
ZEMOSO PRODUCT STUDIO

How to validate your Innovation: Mastering Experiment Design

November 22, 2018
8 min read
ZEMOSO PRODUCT STUDIO

Working Backwards: Amazon's Culture of Innovation: My notes

November 19, 2018
8 min read
ZEMOSO ENGINEERING STUDIO

Product developer POV: Caveats when building with Spark

November 5, 2018
2 min read

Want more best practices?

Access thought-leadership and best practice content across
the product development lifecycle

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.

© 2021 Zemoso Technologies
Privacy Policy

Terms of Use
LinkedIn Page - Zemoso TechnologiesFacebook Page - Zemoso TechnologiesTwitter Account - Zemoso Technologies

© 2021 Zemoso Technologies
Privacy Policy

LinkedIn Page - Zemoso TechnologiesFacebook Page - Zemoso TechnologiesTwitter Account - Zemoso Technologies
June 5, 2022