Spring @Autowired usage


Spring @Autowired usage



What are the pros and cons of using @Autowired in a class that will be wired up by Spring?

Just to clarify, I'm talking specifically about the @Autowired annotation, not auto-wiring in XML.

I probably just don't understand it, but to me it almost seems like an anti-pattern - your classes start to become aware that they are tied to a DI framework, rather than just being POJOs. Maybe I'm a glutton for punishment, but I like having the external XML config for beans, and I like to have explicit wirings, so I know exactly what is wired where.




Type safety: Unchecked cast

1:



Is it possible to use Spring within Eclipse plugins?
For a long time I believed that there was a value in having a "centralized, declarative, configuration" like the xml files we all used to use.


How to design DAOs when the datasource varies dynamically
Then I realized that most of the stuff in the files wasn't configuration - it was never changed anywhere after development, ever.


Basic Spring help
Then I realized that "centralized" only has value in quite small systems - only in small systems will you ever be able to grok a configuration file as a whole.


Problem migrating Spring Web App from tomcat 5.5 to tomcat 6.0
And what is really the value of understanding the wiring as a whole, when the same "wirings" are mostly duplicated by dependencies in the code? So the only thing I've kept is meta-data (annotations), which is still kind-of declarative.


Null Inner Bean with Spring IoC
These never change at runtime and they're never "configuration" data that someone will change on the fly - so I think keeping it in the code is nice..
Use Spring options tag to display enum's toString value
I use full auto-wiring as much as I can.


ACEGI Authentication available in tomcat 404 error handler
I love it.

I won't go back to old-style spring unless threatened at gun-point.

My reasons for preferring fully @Autowired have changed over time.. Right now I think the most important reason for using autowiring is that there's one less abstraction in your system to keep track of.

The "bean name" is effectively gone.

It turns out the bean name only exists because of xml.

So a full layer of abstract indirections (where you would wire bean-name "foo" into bean "bar") is gone.

Now I wire the "Foo" interface into my bean directly, and implementation is chosen by run-time profile.

This allows me to work with code when tracing dependencies and implementations.

When I see an autowired dependency in my code I can just press the "go to implementation" key in my IDE and up comes the list of known implementations.

In most cases there's just one implementation and I'm straight into the class.

Can't be much simpler than that, and I always know exactly what implementation is being used (I claim that the opposite is closer to the truth with xml wiring - funny how your perspective changes!). Now you could say that it's just a very simple layer, but each layer of abstraction that we add to our systems increase complexity.

I really don't think the xml ever added any real value to any system I've worked with.

. Most systems I've ever work with only have one configuration of the production runtime environment.

There may be other configurations for test and so on.. I'd say that full autowiring is the ruby-on-rails of spring: It embraces the notion that there's a normal and common usage pattern that most use cases follow.

With XML configuration you permit a lot of consistent/inconsistent configuration usage that may/may not be intended.

I've seen so much xml configuration go overboard with inconsistencies - does it get refactored together with the code ? Thought not.

Are those variations there for a reason? Usually not.. We hardly use qualifiers in our configuration, and found other ways to solve these situations.

This is a clear "disadvantage" we encounter: We've slightly changed the way we code to make it interact smoother with autowiring: A customer repository no longer implements the generic Repository<Customer> interface but we make an interface CustomerRepository that extends Repository<Customer>.

Sometimes there's also a trick or two when it comes to subclassing.

But it usually just points us in the direction of stronger typing, which I find is almost always a better solution.. But yes, you're tying to a particular style of DI that mostly spring does.

We don't even make public setters for dependencies any more (So you could argue that we're +1 in the encapsulation/information hiding department) We still have some xml in our system, but the xml basically only contains the anomalies.

Full autowiring integrates nicely with xml.. The only thing we need now is for the @Component, @Autowired and the rest to be included in a JSR (like JSR-250), so we don't have to tie in with spring.

This is the way things have been happening in the past (the java.util.concurrent stuff springs to mind), so I wouldn't be entirely surprised if this happened again..


2:


For me here is what I like/dislike about Spring and auto-wiring.. Pros:.
  • Auto-wiring gets rid of nasty XML configuration.
  • Much easier to use annotations which allows you to inject directly using fields, setter methods, or constructors.

    Also allows you to annotate and 'qualify' your injected beans.
Cons:.
  • Using auto-wiring and annotations makes you dependent on Spring libraries where as with XML configuration you could chose to run with or without Spring.

    Like you said, you become tied to a DI framework.
  • At the same time I like being able to 'qualify' beans, to me this makes the code really messy.

    If you need to inject the same bean in multiple places, I've seen the same string name repeated all over.

    To me this seems to have the potential for errors.
I've started using auto-wiring almost exclusively at work because we depend so much on Spring integration anyway that the dependency issue is moot.

I worked on a Spring MVC project that used auto-wiring extensively and was a little hard to wrap my head around.. I think auto-wiring is an acquired taste, once you get used to it you realize how powerful, easy, and much less of a headache it is to work with than the XML configuration..


3:


We are switching from @Autowire back to XML configuration in our big project.

The problem is very low bootstrap performance.

Autowiring scanner loads all classes from autowiring search classpath, so, lots of classes are loaded eagerly during Spring initialization..


4:


There has been very little discussion about switching environments.

Most projects I've worked on it was a real issue to inject dependencies depending on the environment we are working on.

With xml config it's pretty straightforward with Spring EL, and I am not aware of any nice solution with annotations.

I've just figured out one:.
    @Value("#{${env} == "production" ? realService : dummyService}")     private SomeService service; 
It should be working, but not a nice solution imho..


5:


I have switched to @Autowire.

Maintaining the XML configuration on anything other than a small project became a task in it's own right and comprehension quickly degraded.

. IntelliJ provides good (not perfect) support for Spring annotations..


6:


My take on this subject is that, xml configuration reduce the clarity of the code, especially in large systems.

. Annotations like @Component makes things even worse.

It steers developers to make objects mutable, as dependencies can't be made final anymore, given that default constructors need to be provided.

Dependencies need to be either injected through public setter, or uncontrolled through @Autowired.

[even worse dependency injection is compromised with classes that instantiate their dependencies, I still see this in newly written code!].

By uncontrolled I mean, in large systems, when multiple implementations (or children) of the type are available, it gets much more involved to understand which of the implementations was @Autowired, a complexity that makes investigating bugs much harder.

It also means that, supposedly you have a profile for test environment and another for production, your production bugs will only happen when it hurts most - in production, rather than being able to spot the bugs in the test environment, or even better, at compile time!. I stick to the middle ground where I declare my configuration class(es), (java based Spring configuration using @Configuration). I declare all my beans explicitly in the configuration class(es).

I only use @Autowired in the configuration class(es), the purpose is to limit dependency on Spring to the configuration class(es). The @Configuration reside in a specific package, that's the only place where the spring scan runs.

(That speeds up start time substantially in large projects). I strive to make all my classes immutable, especially the data object, JPA, Hibernate and Spring, as well as many serialization libraries seem to undermine this.

I steer away from anything that forces me to provide setters, or remove the final keyword from my property declaration.. Reducing the possibilities of changing objects after they're created, reduces substantially the bugs in large system as well as reduces the time to find a bug when one exists.

. It also seems that it forces developer to better design the interaction between the different parts of the system.

Problems and bugs become more and more compilation errors, that reduces wasted time and improve productivity..


7:


Here are some of experience
Pros
.
  • Makes easier to configure because we can just use @Autowire annotation
  • Don't want to use setter methods , so class will be more clean
Cons.
  • Tightly couple to xml file even though we are using DI
  • Hard to find implementation (But if you your using good ides like intellij sure you can get rid of this)
As of my personal experiences I didn't use @AutoWire annotation that much but in test cases.

.


8:


I really love write with annotations, instead of XML.

According to the Spring manual and the last versions, XML and Annotation achieved the same result.. This is my list. Pro:.
  • Remove useless line from xml
  • Simplify the debugging the code: when you open a class, you can read what you have in the class
  • More fast developping, a project with 400 or more line of XML is readable?
Cons:.
  • Is not standard Java implementation, but you can switch to use @Inject, which is a Java Standard Api, so the bean remain a Pojo
  • You cannot simply use everywhere, db connection e so on, but it's only an opinion, i prefer have a place where read all configuration.




86 out of 100 based on 66 user ratings 566 reviews