Nicolas Frankel is an IT consultant with 10 years experience in Java / JEE environments. He likes his job so much he writes technical articles on his blog and reviews technical books in his spare time. He also tries to find other geeks like him in universities, as a part-time lecturer. Nicolas is a DZone MVB and is not an employee of DZone and has posted 218 posts at DZone. You can read more from them at their website. View Full User Profile

The Case for Spring Inner Beans

02.11.2013
| 6428 views |
  • submit to reddit

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.

Published at DZone with permission of Nicolas Frankel, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Dan Holmes replied on Mon, 2013/02/11 - 12:21pm

I'm not sure I agree that prototype scope doesn't mean anything for inner beans. With default prototype scope, if you create 10 instances of bean five, you'll get 10 instances each of beans one, two, three, and four. If those inner beans were set to singleton scope, you'd get 10 instances of five, but a single shared instance of one, two, three, and four.

Am I missing something?

Nicolas Frankel replied on Mon, 2013/02/11 - 12:33pm in response to: Dan Holmes

Well, it's how it's described in the documentation. You're welcome to unit-test their assertions, I would really be interested in the results.

Dan Holmes replied on Tue, 2013/02/12 - 12:37pm

I ran some tests. The documentation is correct - the inner beans appear to always be prototype scope. However, your conclusion that "this doesn't mean squat" is incorrect. Forced prototype scope means a lot. If you instantiate bean five multiple times, you will get multiple, distinct instances of beans one, two, three, and four. If you want singleton behavior (a single instance of bean one for several instances of bean five), I think you are out of luck. Developers should understand this limitation very carefully. If a given design requires singleton behavior, this will mean that inner beans should be avoided.

Nicolas Frankel replied on Tue, 2013/02/19 - 4:20am in response to: Dan Holmes

 Following my article, Oliver Gierke created this Jira. It seems the two of you disagree...

Dan Holmes replied on Tue, 2013/02/19 - 11:11am

Actually, I think he confirmed my point. If I'm reading the ticket correctly (which is difficult - there's not much detail there), he also demonstrated that multiple instances of the inner beans are created. He's disputing whether they should have destruction callbacks applied, which has nothing to do with the original article or any of my comments. I'm not even sure he's correct when he says that prototypes shouldn't be affected by lifecycle methods, but it's unrelated to the point I was trying to make, so I won't worry about it.

Nicolas, are you of the opinion that there will only ever be a single instance of each defined inner bean, no matter how many instances of the "outer" bean are created? If so, that's not prototype scope, that's singleton scope. Or, are you of the opinion that multiple instances of the inner beans can be created? If so, that's prototype scope, but then it's wrong to say it "doesn't mean squat". It means a lot, and if you need to restrict the bean to a single instance in the container, you apparently can't do it with an inner bean definition.

I'm not trying to be a jerk. I just think there's possibly a bit of misinformation in your article, and I'd hate to see someone misled and subsequently introduce some unexpected behavior into their code.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.