Nuts Moduling
Nuts has a flexible moduling system that makes organizing components easier.
import
Each Nuts configuration file is a module. A module file can explicitly import other configuration module files.
syntax
<import> tag is used to do the importing. For example:
<import file="basic_components.xml" includes="a,b,c*" excludes="cat*"
namespace="basic"/>
<import resource="basic_components.xml" classpath="basic.jar" includes="*"/>
The attributes of <import> tag are:
- includes. Mandatory attribute. It determines which components are included in this import. Either "*" or explicit list of names have to be specified. Wildcard can be appended to any valid id to denote a search by prefix.
- excludes. Optional attribute. The syntax is same as "includes" except it specifies the list of names excluded from the import.
- namespace. Optional attribute. If "namespace" is not specified, the components imported are directly put into the global namespace. When it is specified, for example, namespace="my" is specified, all components imported will be named in the pattern "my.xxx" where xxx is the original name defined in the original file.
- file. Denotes the filename to be imported. The path is relative to the location of the current configuration file.
- resource. Denotes the name of a resource that can be loaded from either the current class loader or an alternative class path. "file" and "resource" cannot be both specified.
- classpath. The alternative class path to search for the resource. This attribute can only be specified when "resource" is specified.
Odds and Ends
The syntax of <import> is easy. But there are a few things to be noted:
- The same module file or resource can be imported more than once. For example:
<import file="a.xml" namespace="a1" includes="*"/>
<import file="a.xml" namespace="a2" includes="*"/>
The above configuration is legal as long as "includes", "exludes", "namespace" are properly used so that there's no name clash.
- A module file is evaluated at most once. Even when "a.xml" is imported twice, the components in it are evaluated only once. Thus, singleton components are still singleton even when they are imported more than once and registered under different key.
- <import> may break auto-wiring. Bytype autowiring can be broken because there may be more than one objects for the same type; Byname and byQualifiedName autowiring can also be broken because the components may be now registered with a namespace.
- Refrain from using the wildcard character "*" for the "includes" attribute. It can easily become a nightmare for maintainance when "*" is abused. Because it is not easy to know what exactly is imported.
Dependency Injection for Configuration Modules
Typically, dependencies of components are all manual-wired within xml configuration files. Yet, it may still be useful sometimes to provide dependency to the xml configuration file from within Java.
Such requirement can be implemented by global dependency declared by the "depends" attribute of the <module> tag.
For example:
<module name="test" depends="account_id, balance">
<body>
<bean id="account" class="BankAccount">
<prop key="accountid" val="$account_id"/>
<prop key="balance" val="$balance"/>
</bean>
</body>
</module>
The above configuration module is not self-contained because it depends on two components named "account_id" and "balance" to be injected. When instantiating, the key "account_id" and "balance" have to be present in the container.
The following Java code injects the dependencies and glues everything together:
NutsProcessor processor = new NutsProcessor();
Container yan = processor.getContainer();
yan.registerValue("account_id", myaccount_id);
yan.registerValue("balance", mybalance);
processor.processFile("test.xml");
BankAccount acct = (BankAccount)yan.getInstance("account");
The myaccount_id and mybalance will then be wired to the BankAccount object.
Created by benyu
On Sun Nov 20 18:11:39 CST 2005
Using TimTam