Abstract beans that have no class - No Fluff Just Stuff

Abstract beans that have no class

Posted by: Craig Walls on April 28, 2006

I've been thinking that it'd be nice if there was a way in Spring to declare a set of default injections so that if a bean has one of the properties defined in the set of default injections that it'd automatically be wired.

For example, in a typical Spring web application, you may have several controllers, all of which reference the same service bean. For each controller, you must wire in the service bean as follows:

<bean id="someController" class="MyController">
...
  <property name="someService" ref="myService" />
...
</bean>

This is no big deal if you have only one or two controllers. But it seems a bit tedious to add the same property definition to each and every controller definition, especially if there are a dozen or so controllers.

Wouldn't it be nice to somehow declare (perhaps at the <beans>) level) something like this:

<property name="someService" ref="myService" />

Then, when Spring creates any bean (controller or not), it will wire the "someService" property with "myService" if the bean has that property. If the bean doesn't have the property, then it just moves on with no errors. It's almost like a kind of autowiring, only with a little more control over what gets wired.

Well, unless someone knows a trick that I've not discovered yet, this isn't possible (yet--hint hint to the Spring team). But we can get close by using class-less abstract beans.

I've known for a long time that I can do something like the following:

<bean id="baseBean"
    class="BaseBean"
    abstract="true">
  <property name="foo" value="FOO" />
</bean>

<bean id="realBean"
    parent="baseBean">
  <property name="bar" value="BAR" />
</bean>

In this case, "realBean" is a sub-bean of "baseBean" and inherits it's value for "foo". The only problem is that "realBean" must be the same type as "baseBean". This doesn't help me with my controllers, of which each are different types.

So, I scratched my head and pondered: Can I create an abstract bean and not set the class attribute and then use both parent and class attributes on the sub-bean? Something like this:

<bean id="baseController"
    abstract="true">
  <property name="someController" ref="myController" />
</bean>

<bean id="someController"
    class="MyController"
    parent="baseController" />

Here, the "baseController" bean abstractly wires up some properties, but to no specific type. Then, the "someController" bean extends the "baseController" bean, thus inheriting its properties, and is concretely defined as being a MyController.

So does this work? You betcha!

Turns out that Spring's been able to do this for awhile (it's even documented in section 3.5 of the reference document). But it's somehow managed to stay under my radar until recently.

I still would like a way of specifying properties that might be on the beans (and quietly move on without an error if the bean doesn't have the property). And, it'd be nice if it was a global property setting so that I don't have to use the parent attribute. But class-less abstract beans aren't a bad start.

Craig Walls

About Craig Walls

Craig Walls is a Principal Engineer, Java Champion, Alexa Champion, and the author of Spring AI in Action, Spring in Action, and Build Talking Apps. He's a zealous promoter of the Spring Framework, speaking frequently at local user groups and conferences and writing about Spring. When he's not slinging code, Craig is planning his next trip to Disney World or Disneyland and spending as much time as he can with his wife, two daughters, 1 bird and 2 dogs.

Why Attend the NFJS Tour?

  • » Cutting-Edge Technologies
  • » Agile Practices
  • » Peer Exchange

Current Topics:

  • Languages on the JVM: Scala, Groovy, Clojure
  • Enterprise Java
  • Core Java, Java 8
  • Agility
  • Testing: Geb, Spock, Easyb
  • REST
  • NoSQL: MongoDB, Cassandra
  • Hadoop
  • Spring 4
  • Cloud
  • Automation Tools: Gradle, Git, Jenkins, Sonar
  • HTML5, CSS3, AngularJS, jQuery, Usability
  • Mobile Apps - iPhone and Android
  • More...
Learn More »