Performance Zone is brought to you in partnership with:

Nicolas Frankel is an IT consultant with 10 years experience in Java / JEE environments. He likes his job so much he writes technical articles on his blog and reviews technical books in his spare time. He also tries to find other geeks like him in universities, as a part-time lecturer. Nicolas is a DZone MVB and is not an employee of DZone and has posted 231 posts at DZone. You can read more from them at their website. View Full User Profile

My Case Against Autowiring

11.03.2013
| 7663 views |
  • submit to reddit

Autowiring is a particular kind of wiring, where injecting dependencies is not explicit but actually managed implicitly by the container. This article tries to provide some relevant info regarding disadvantages of using autowiring. Although Spring is taken as an example, the same reasoning can apply to JavaEE’s CDI.

Autowiring basics

Autowiring flavors

Autowiring comes into different flavors:

  • Autowiring by type means Spring will look for available beans that match the type used in the setter. For example, for a bean having a setCar(Car car) method, Spring will look for a Car type (or one of its subtype) in the bean context.
  • Autowiring by name means Spring search strategy is based on beans name. For the previous example, Spring will look for a bean named car regardless of its type. This both requires the bean to be named (no anonymous bean here) and implies that the developer is responsible for any type mistmatch (if the car bean is of type Plane).

Autowiring is also possible for constructor injection.

Autowiring through XML configuration

Let’s first dispel some misconceptions: autowiring does not imply annotations. In fact, autowiring is available through XML since ages and can be enabled with the following syntax.

<bean autowire="byType" class="some.Clazz" />

This means Spring will try to find the right type to fill the dependency(ies) by using setter(s).

Alternative autowire parameters include:

  • by name: instead of matching by type, Spring will use bean names
  • constructor: constructor injection restricted to by-type
  • autodetect: use constructor injection, but falls back to by-type if no adequate constructor is found
Autowiring through annotations configuration

Available annotations are the following:

Annotation Description Source
 org.springframework.bean.factory.@Autowired  Wires by type  Spring 2.5+
 javax.annotation.@Resource  Wires by name  JavaEE 5+
 javax.inject.@Inject  Wires by type  JavaEE 6+
javax.inject.@Qualifier  Narrows type wiring  JavaEE 6+

Dependency Injection is all about decoupling your classes from one another to make them more testable. Autowiring through annotations strongly couples annotated classes to annotations libraries. Admittedly, this is worse for Spring’s @Autowired than for others as they are generally provided by application servers.

Why it is so bad after all?

Autowiring is all about simplifying dependency injection, and although it may seem seductive at first, it’s not maintainable in real-life projects.

Explicit dependency injection is – guess what, explicitly defining a single bean to match the required dependency. Even better, if Java Configuration is used, it is validated at compile time.

On the opposite, autowiring is about expressing constraints on all available beans in the Spring context so that one and only one matches the required dependency. In effect, you delegate wiring to Spring, tasking him to find the right bean for you. This means that by adding beans in your context, you run the risk of providing more than one match, if your previous constraints do not apply to the new beans. The larger the project, the larger the team (or even worse, the number of teams), the larger the context, the higher the risk.

For example, imagine you crafted a real nice service with a single implementation, that you need to inject somewhere. After a while, someone notices your service but creates an alternative implementation for some reason. By just declaring this new bean in the context, along with the former, it will break container initialization! Worse, it may be done in an entirely different part of the application, with seemingly no link with the former. At this point, good luck to analyze the reason of the bug.

Note that autowiring by name if even worse, since bean names have a probability of collision, even across different type hierarchies.

Autowiring is bad in Spring, but it is even worse in CDI where every class in the classpath is a candidate for injection. By the way, any CDI guru reading this post care to explain why autowiring is the only way of DI? That would be really enlightening.

Summary

In this post, I tried to explain what is autowiring. It can be used all right, but now you should be aware of its con. IMHO, you should only use it for prototyping or quick-and-dirty proof of concepts, everything that can be discarded after a single use. If really needed, prefer wiring by type over wiring by name as at least it matching doesn’t depend on a String.

 

Published at DZone with permission of Nicolas Frankel, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)