Mailing List Question: @Autowired Ambiguities

Today a question went out on a Spring mailing list asking about @Autowired dependencies, AOP proxies, and interfaces. I thought this was a great foundation question. So I thought I'd share it here.

Say you have a bean class, Foo which implements FooInterface. On top of that, the bean is advised via Spring AOP it is the proxy class which is referenced by the context (IOC). Now, let's say you want to autowire that dependency in another bean. So you mark the Foo field @Autowired. You fire up you application. Much to your dismay, you'll get an error message on context initialization which goes something like, "unsatisfied dependency." This is due to the fact that you are trying to autowire an object by its class but that class has been proxied. Meaning that there are no beans of this type in context.

So, you remember that its a great idea to code against interfaces rather than concrete classes. So you adjust your field type to FooInterface and fire up the application again. Unfortunately, you forgot that there are several instances of FooInterface in context and you get another error on startup. "No unique bean of type..."

So how would I autowire a specific bean out of a set? The answer is the handy @Qualifier annotation. Adding this to your autowired field let's you specify the bean id/name to inject. In this case you'd use something like @Qualifier("stevesFoo"). Boom. Done.

Note: JPA InheritanceType.JOINED

Hey, make sure to annotate child model classes with @PrimaryKeyJoinColumn when using InheritanceType.JOINED. This annotation allows you to specify the column names to be used in mapping parent child relationships.

Additional reading:

  1. API
  2. JEE 6 - Entity Inheritance Tutorial - fantastically incomplete
Its important to note that using this inheritance model requires an extra join operation when retrieving entities. This may negatively impact performance if running high volume or with anything other than trivial inheritance models.

Spring's Alternative Configuration Features

A primary complaint about Spring is the heavy XML configuration traditionally required to use it in a non-trivial way. More and more recent releases have made significant strides away from this model. With the introduction of annotation-based container configuration, Component beans, component scanning, and finally configuration beans, that argument has been largely deflated. These tools move significant portions of configuration from XML into annotation based equivalents. Combined with highly configurable classpath scanning, many traditional component beans like services or repositories can be auto instantiated and auto wired. This is a miracle for larger projects with hundreds of these singleton beans. But some of you might just be saying, "Doesn't this just move configuration from one common place, outside of code, into the code itself?" For those of you who have spent years fighting to get configuration out of code, this might seem all kinds of wrong. Well, if you find yourself in either of these groups - you're not alone - you are both right and wrong.

The reason is simple. All of that configuration, really isn't application configuration at all is it? Think of it this way, if you were not using a dependency injection pattern, all of this bean wiring is something that you would be doing in code by passing dependencies along in method signatures, or some other mechanism. We've all been there, and none of us want to go back. It is Spring configuration, not application configuration. In many instances these tools provide more powerful means of accessing your actual application configuration, which is why we use these frameworks. These make our lives more simple.

Simple is nice. But powerful is awesome. Enter the Spring configuration bean. These are beans which, when loaded via XML or component scanning, define beans to be loaded into the context. With these tools you can finally debug and unit test Spring configuration at a granular level, as well as create configuration inheritance models. Boom. But maybe the best reason to use this stuff is that it makes your Spring configuration much more reusable. No more copying chunks of XML, no more massive efforts to upgrade code bases. So, before you dismiss this stuff too quickly, take a few moments and try to think about how you could use it without violating your personal coding ethics. It will pay out in spades.

Oh, and for those of you who are still a bit buried in your XML configuration bunkers, good luck with the Servlet 3 specification.