Home > Java > The case for Spring inner beans

The case for Spring inner beans

When code reviewing or pair programming, I’m always amazed by the following discrepancy. On one hand, 99% of developers conscientiously apply encapsulation and limit accessibility and variable scope to the minimum possible. On the other hand, nobody cares one bit about Spring beans and such beans are always set at top-level, which makes them accessible from every place where you can get a handle on the Spring context.

For example, this a typical Spring beans configuration file:

<bean id="one" class="ch.frankel.blog.spring.One" />
<bean id="two" class="ch.frankel.blog.spring.Two" />
<bean id="three" class="ch.frankel.blog.spring.Three" />
    <property name="one" ref="one" />
    <property name="two" ref="two" />
</bean>
<bean id="four" class="ch.frankel.blog.spring.Four" />
<bean id="five" class="ch.frankel.blog.spring.Five">
    <property name="three" ref="three" />
    <property name="four" ref="four" />
</bean>

If beans one, two, three and four are only used by bean five, they shouldn’t be accessible from anywhere else and should be defined as inner beans.

<bean id="five">
    <property name="three">
        <bean class="ch.frankel.blog.spring.Three">
            <property name="one">
                <bean class="ch.frankel.blog.spring.One" />
            </property>
            <property name="two">
                <bean class="ch.frankel.blog.spring.Two" />
            </property>
        </bean>
     </property>
     <property name="four">
         <bean class="ch.frankel.blog.spring.Four" />
     </property>
</bean>

From this point on, beans one, two, three and four cannot be accessed in any way outside of bean five; in effect, they are not visible.

There are a couple of points I’d like to make:

  1. By using inner beans, those beans are implicitly made anonymous but also scoped prototype, which doesn’t mean squat since they won’t be reused anywhere else.
  2. With annotations configuration, this is something that is done under the cover when you set a new instance in the body of the method
  3. I acknowledge it renders the Spring beans definition file harder to read but with the graphical representation feature brought by Spring IDE, this point is moot

In conclusion, I would like every developer to consider not only technologies, but also concepts. When you understand variable scoping in programming, you should not only apply it to code, but also wherever it is relevant.

email
Send to Kindle
Categories: Java Tags:
  1. February 11th, 2013 at 10:38 | #1

    Minor correction: inner beans *do not become prototypes*. The XML is just evaluated as you’d expect it if you defined two beans of the same type with different ids: you get two singleton instances of the same type. This is important as prototypes are te different beasts (e.g. they are not subject do bean destruction callbacks etc.) so that I think it’s worth clarifying.

    Beyond that: good post! :)

  2. February 11th, 2013 at 10:41 | #2

    Hi Oliver,
    From what I understand from Spring documentation, there’s a contradiction. Would it be worth to update the documentation then?

  3. Kim
    February 11th, 2013 at 11:54 | #3

    Amen!

    And this problem becomes even bigger with Spring’s Java based configuration that doesn’t have a proper concept of inner beans.

  4. February 11th, 2013 at 12:04 | #4

    That’s what I thought at first. But after some afterthought, I think local variables created inside @JavaConfig methods are akin to inner beans.

  5. February 18th, 2013 at 12:10 | #5

    @Nicolas Frankel Indeed, there is. In fact, the beans do *not* become prototype scoped beans, they just feel like prototypes as you get a dedicated instance per injection/declaration point. As I also think that the reference documentation is misleading on that side of things, I’ve created a ticket to improve it: https://jira.springsource.org/browse/SPR-10311.

  6. February 18th, 2013 at 13:52 | #6

    @Oliver Gierke
    You rock :-)

  1. No trackbacks yet.