Print
Module System Compared

Overview

Module system is primarily concerned with the xml configuration file. When writing in Java, we can always use java packages and classes to modularize components anyway.

Therefore, this comparison is between Spring and Nuts. Pico is skipped.

Spring allows configuration to be put into different xml file and later on merged together. Though Spring reference does not call it a module, this support is refered to as "module" in this comparison.

There are basically two ways of merging the xml files:

  1. Java code that loads separate xml files who are ignorant of each other. Beans within each xml file can either override each other, or, organized in an ApplicationContext tree.
  2. xml configuration file can explicitly use <import> tag to include beans defined in another xml file.

These two ways both have pros and cons. The first way is ideal for loading configuration files that are inherently independent of each other. While the latter is better when configuration file needs to be refactored to get smaller size and better modularity.

Nuts has quite similar functionality as Spring as far as the first approach is concerned (though there's a slight difference that we will mention later).

It is the <import> facility that distinguish Nuts and Spring's module system.

<import>

The Spring <import> tag has quite limited functionality. When

<import resource="services.xml"/>

is called, all beans defined in the services.xml are loaded into the current ApplicationContext. There's no concept of "module private" beans who are only visible to the containing module file.

Plus, when beans from two imported xml files share the same name, (which is very possible if the two xml files are created independently), Spring offers no solution for resolving the name clash other than a simple "override".

In contrast, Nuts provides a more elaborate moduling system.

First, each module file has a <module> tag that defines the module properties. The "export" and "hide" attributes of <module> can be used to keep certain beans to be "module private".

For example:

<module name="a" export="a,b*" hide="bc*">
<body>
  <bean id="a" .../>
  <bean id="b" .../>
  <bean id="bc" .../>
  <bean id="bd" .../>
  <bean id="c" .../>
</body>
</module>

bean "bc" and "c" will be kept as private beans that no other module can ever see. While "a", "b", "bd" are exported.

Secondly, <import> tag has "includes" and "excludes" attributes that allows selective import.

For example, if both a.xml and b.xml export bean "ab", I can use the "ab" from a.xml, and ignore the "ab" from b.xml:

<import file="a.xml" includes="*">
<import file="b.xml" includes="*" excludes="ab"/>

Finally, when two beans from two xml files share the same name, yet I do need both, <import> has an attribute "namespace" for us to distinguish them:

<module name="c">
<import file="a.xml" includes="*" namespace="a"/>
<import file="b.xml" includes="*" namespace="b"/>
<body>
  <bean id="x" class="X" props="{name=$a.name}"/>
  <ctor id="y" class="Y" args="$b.name"/>
</body>
</module>

Both "name" components imported from a.xml and b.xml are used in the module c. But the name is prefixed with a namespace to prevent name clashing.

"depends"

Spring support <ref> tag that allows one bean to use another. The <ref local="..."/> form is same as Nuts' variables prefixed by the '$' character. It only references beans defined in the current xml file, which allows early error detection.

The <ref bean="..."/> form is more general. It can point to any bean that will eventually end up in the ApplicationContext.

Same as Spring, Nuts encourages the use of local reference because it is cleaner. And, Nuts has no syntax for <ref bean="..."/> at all. Every reference has the same form "$referencename". Nuts doesn't allow any reference whose name is not declared in the current xml file.

Although this sounds like a restriction, Nuts does allow you to reference components not defined in the current xml file. They have to be declared, but don't have to be defined.

The <module> tag has a "depends" atttribute that accepts a list of names. These names are considered as the names of the beans defined externally and will eventually end up in the container.

For example:

<module name="my module" depends="global_x, global_y">
<body>
  <bean id="acct" class="BankAccount" props="{x=$global_x, y=$global_y}"/>
</body>
</module>

The "acct" bean references two externally defined components that are only declared by the "depends" attribute.

Pros? Cons?

Spring's way is a bit handier because you don't have to specify the "depends" attribute. (The <ref bean="..."/> syntax somewhat pays back though.)

While Nuts' way is clearer and safer because part of the error checking (like typos) for these external components can still be done as early as possible.


Created by benyu

On Mon Nov 28 17:47:55 CST 2005

Using TimTam

Powered by Atlassian Confluence