DZone
Java Zone
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
  • Refcardz
  • Trend Reports
  • Webinars
  • Zones
  • |
    • Agile
    • AI
    • Big Data
    • Cloud
    • Database
    • DevOps
    • Integration
    • IoT
    • Java
    • Microservices
    • Open Source
    • Performance
    • Security
    • Web Dev
DZone > Java Zone > @Autowired and Optional Dependencies

@Autowired and Optional Dependencies

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

Sebastian Malaca user avatar by
Sebastian Malaca
·
Mar. 09, 16 · Java Zone · Analysis
Like (8)
Save
Tweet
18.84K 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.

Popular on DZone

  • You Are Blind to the Risks in Your Cloud — Why Companies Need Cloud Security Monitoring
  • Fun With Modules
  • XAMPP vs WAMP: Which Local Server Is Best?
  • Why Should You Choose ReactJS for Your Next Project?

Comments

Java Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

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

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends:

DZone.com is powered by 

AnswerHub logo