DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

SBOMs are essential to circumventing software supply chain attacks, and they provide visibility into various software components.

Related

  • While Performing Dependency Selection, I Avoid the Loss Of Sleep From Node.js Libraries' Dangers
  • Why I Started Using Dependency Injection in Python
  • Understanding ldd: The Linux Dynamic Dependency Explorer
  • Understanding the Two Schools of Unit Testing

Trending

  • Advanced gRPC in Microservices: Hard-Won Insights and Best Practices
  • Why Traditional CI/CD Falls Short for Cloud Infrastructure
  • How We Broke the Monolith (and Kept Our Sanity): Lessons From Moving to Microservices
  • How to Troubleshoot Common Linux VPS Issues: CPU, Memory, Disk Usage
  1. DZone
  2. Software Design and Architecture
  3. Security
  4. @Autowired and Optional Dependencies

@Autowired and Optional Dependencies

Are your injected dependencies required or optional? What about all the permutations of possibilities?

By 
Sebastian Malaca user avatar
Sebastian Malaca
·
Mar. 09, 16 · Analysis
Likes (8)
Comment
Save
Tweet
Share
23.0K Views

Join the DZone community and get the full member experience.

Join For Free
@Autowired annotation makes our lives easier. It also can result in a decreased amount of code if we are using it on properties of the class. We need neither constructors nor setter methods. It looks great at first glance, but the benefits rarely come without cost. Today I want to make you aware of the costs that have to be paid.

@Autowired(required=false)

@Autowired annotation by default has an element "required" set to true, which means that the annotated dependency is required. However, we can turn off the default behavior and make the dependency optional as follows:
@Autowired(required=false)
private Dependency dependency;
It can be useful, and since not all dependencies are always required, introducing this possibility was reasonable.

So what’s the problem with dependencies annotated in this way? Let’s look at the code:

class SomeClass {
 @Autowired private DependencyA dependencyA;
 @Autowired private DependencyB dependencyB;

 @Autowired(required=false)
 private DependencyC dependencyC;

 @Autowired(required=false)
 private DependencyD dependencyD;
}
We can create an instance of the SomeClass with following dependencies (all combinations are allowed):
  • DependencyA, DependencyB
  • DependencyA, DependencyB, DependencyC
  • DependencyA, DependencyB, DependencyD
  • DependencyA, DependencyB, DependencyC, DependencyD
And this is all great, but are you sure that all of those combinations are really useable and correct? What if the author of the class thought only about 1 and 4?

Optional Dependencies - Do it Right!

If we are considering an example presented in the previous paragraph, there are two possible answers to the following question:
  • All combinations are possible.
  • Only a subset of the combinations is possible.
In the case when all combinations are possible, I would leave the code as it is. If there is nothing that can go wrong and each state of the object is correct, then our code is descriptive enough. It clearly allows for anything so we can assume that anything that we will do will result in the creation of an object that we may work with.

What about the second point - a subset of the combinations? Let’s assume that only creating an object in either state 1 or state 4 is valid. Leaving the code as it is can result in the wrong usage of the object. We are allowing for the creation an object in invalid states (2 and 3). What can we do about this?

In that case, I think that we should drop @Autowired annotation. For the sake of the code readability and design quality it would be better to use constructors instead:

class SomeClass {
 private DependencyA dependencyA;
 private DependencyB dependencyB;
 private DependencyC dependencyC;
 private DependencyD dependencyD;

 public SomeClass(DependencyA dependencyA, DependencyB dependencyB) {
 this.dependencyA = dependencyA;
 this.dependencyB = dependencyB;
 }

 public SomeClass(DependencyA dependencyA, DependencyB dependencyB, DependencyC dependencyC, DependencyD dependencyD) {
 this(dependencyA, dependencyB);
 this.dependencyC = dependencyC;
 this.dependencyD = dependencyD;
 }
}

With this code, you know everything that is needed. You know what dependencies are required to create a correct object.

Stay Aware!

The article is not intended to convince you that it is better to not use @Autowired(required=false). Its purpose is to make you aware of the cost that you have to pay.

You have to protect your design, you have to protect object invariants and you should not allow for the existence of the objects in an invalid state. Of course, you may add a documentation or comment, but if we already have a semantic provided by the language which allows us to make it without additional effort we should use it.

Dependency

Published at DZone with permission of Sebastian Malaca, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • While Performing Dependency Selection, I Avoid the Loss Of Sleep From Node.js Libraries' Dangers
  • Why I Started Using Dependency Injection in Python
  • Understanding ldd: The Linux Dynamic Dependency Explorer
  • Understanding the Two Schools of Unit Testing

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • [email protected]

Let's be friends: