CDI worse than Spring for autowiring?
Let’s face it, there are two kinds of developers: those that favor Spring autowiring because it alleviates them from writing XML (even though you can do autowiring with XML) and those that see autowiring as something risky.
I must admit I’m of the second brand. In fact, I’d rather face a rabbied 800-pounds gorilla than use autowiring. Sure, it does all the job for you, doesn’t it? Maybe, but it’s a helluva job and I’d rather dirty my hands than let some cheap bot do it for me. The root of the problem lies in the implicit-ness of autowiring. You declare two beans, say one needs a kind of the other and off we go.
It seems simple on the paper and it is if we let it at that. Now, autowiring comes into two major flavors:
- By name where matching is done between the property’s name and the bean’s name
- By type where matching is done between the property’s type and the bean’s type
The former, although relatively benign, can lead to naming nightmares where developers are to tweak names to make them autowire together. The second is an utter non-sense: in this case, you can create problems in a working context by creating a bean in it, only because it has the same class as another bean already existing in the context. Worse, autowiring errors can occur in a completely unrelated location, just because of the magic involved by autowiring. And no, solutions don’t come from mixing autowiring and explicit wiring, mixing autowiring between name and type or even excluding beans from being candidates for autowiring; that just worsens the complexity as developers have to constantly question what will be the behavior.
Autowiring fans that are not convinced should read the Spring documentation itself for a list of limitations and disadvantages. This is not to say that autowiring in itself is bad, just that is has to be kept strictly in check. So far, I’ve allowed it only for small teams and only for tests (i.e. code that doesn’t ship to production).
All in all, Spring autowiring has one redeeming quality: candidates are only chosen from the context, meaning instances outside the context cannot wreak havoc our nicely crafted application.
CDI developers should have an hint where I’m heading. Since in CDI every class on the classpath is candidate for autowiring, this means that adding a new JAR on the application’s classpath can disrupt CDI and prevent the application from launching. In this light, only autowiring by name should be used for CDI… and then, only by those courageous to take the risk

Autowiring by type in Spring works okay for me. But I do use it very selectively. Where I have one bean ever of that type used in lots of places I tend to autowire that bean by type rather than clutter the XML file. Identifying such beans doesn’t give me a problem so far.
I think the only place I use autowire by name is in test code.
In a couple of cases I use the component-scan to define the beans and inject a list of them into a class. That’s more auto-defining than autowiring I guess. But it also reduces the XML clutter, so I think of it as similar.
Your arguments remind me of the story about the evolution of New York and cars. Back in the early days there were no cars in New York, only horses.. lots of em. These horses produced tons of horse shit each day, creating gigantic piles of horse shit. Everybody was complaining about it. Then one dude introduced the car and in the next decade the cars replaced the horses and New York was elevated from the horseshit issue. Now there are millions of cars in New York and everybody is complaining about the traffic jams and pollution produced by cars.
The point being, Spring is to the pile of coding shit as the car was to the pile of horse shit: it solved a big issue.
Did the cars solve all the problems? No, neither did Spring. But can you imagine a New York where each car was replaced by a horse? No?, me neither. I think Spring did a nice job. If you use the configuration annotations you can circumvent the issue with the duplicate bean names quite easily and elegant (as you could with the XML configuration) without uglifying your actual implementation classes.
CDI i haven’t tried yet so you’re probably right on that one
I don’t see where in my article I complained about Spring: the point is implicit vs explicit and in that area, autowiring just sucks.
Well, adding a new JAR on the application’s classpath can disrupt nearly everything, even spring with explicit wiring.
You can wire without @Autowired or XML. You can define @Component classes, by putting one of the @Component derivatives on the bean def, with value defined. Of course the package must be put in the classpath scan in your xml. Use: @Component(value=”xyzThing”) . Then instead of Autowiring by type you would use javax.annotation.Resource like: @Resource(name=”xyzThing”) on your field in the class that needs it injected. This “by name” will actually work when Autowiring fails because of multiple bean definitions of the same type (which I’ve used) or your thing to be injected has too many types (proxies) and Spring can’t figure out which one. Here think of a CXF service with Transactional and other behaviors added via AOP. It can fail quietly at context start but create a NPE on use.
@Randy Motluck
It can fail, meaning Autowiring can fail quietly.
Actually I’m failing to see what’s your point about auto-wiring being so bad. What exact problem do you have with it?
Adding things to an application always can break stuff. If a newly added beans causes auto-wiring to fail, Spring as well as CDI will fail fast with a clear report of the problem. So far I don’t see a reason for not using auto-wiring in production code, it’s determinstic and IMO *much* simpler to maintain than tons of XML context files. In our project we’re also having an automated integration test which fails immediately in case there are wiring problems.
So don’t get me wrong, I just would like to better understand what your arguments against auto-wiring are, from the post I’ve understood so far only some guts feeling of yours.
IMO, the problem of autowiring is its implicit nature. By wiring explicitly, I see exactly what I do. Hell, I can even visualize it graphically with Spring IDE! No such luck with autowiring. Worse, I can disrupt one part of my application by creating a class in another part.
For large teams, this is exactly what I try to prevent.
@Nicolas Frankel
By wiring explicitly, I see exactly what I do.
Following that argumentation you should avoid convention-over-configuration approaches in general, as they never are explicit. It’s always a trade-off between understandability and saving efforts, but I tend to prefer implicit approaches (as long as they are deterministic, which CDI absolutely is) and thus save efforts/time.
Hell, I can even visualize it graphically with Spring IDE!
Sounds nice, though I’ve never felt I’m in need for that. And I imagine some issues with visualizing object graphs with thousands of beans.
Worse, I can disrupt one part of my application by creating a class in another part.
As I said this can happen anyways, so this is no argument against auto-wiring. If I’m adding a bean to one of 100 Spring context files I can break my application, too (and worse, not even notice it if the bean just overwrites another one). CDI quickly fails in such cases, and a simple test can show in an automated manner whether everything works or not.
For large teams, this is exactly what I try to prevent.
In my experience XML based Spring contexts are a pure nightmare in large teams. Context files easily lose their structure, it’s hard to say which beans should go into which context file, which order of files is applied etc. I’m also missing some advice by the Spring team for organizing contexts in huge environments.
All in all I’d always prefer auto-wiring over XML config and definitely recommend to give it try if you haven’t done so.
>…that adding a new JAR on the application’s classpath can disrupt CDI and prevent the application from launching
That isn’t true and it shows that you don’t really know CDI. If a JAR doesn’t include a marker file called beans.xml, it will be ignored. Name based dependency injection isn’t type-safe and therefore the worst you can do. You should really have a look at qualifiers, if you have multiple sub-types of a class. Furthermore, CDI shows all issues already during the startup and not if you hit the bug and it’s too late like Spring does.
> only autowiring by name should be used for CDI
OMG, what a *pieeep* argumentation. Sorry, but it’s just completely wrong.
That’s like claiming that having java.util.List makes it impossible to implement your own List implementation… Ever heard of java packages?
CDI provides _tons_ of mechanism to even have different ‘Bean’ for the same class. You can use Qualifiers, producer methods, etc And it’s _much_ faster than spring as 95% of the effort is done when the container starts and not always evaluated on the fly. Let alone that the chance of a name conflict or simply a typo at an injection point will blow up your Spring application if you don’t resolve by type. And the worst: you will only see this at runtime thus you really need to ensure that you have 100% branch coverage in your tests …