Tom Whitner
11-23-2004, 06:19 PM
I have begun working with child object definitions to deal with common configuration across classes of objects. Initially, I mapped the base definitions to the corresponding abstract type, but then realized that this was just coincidence as the object definition really had nothing to do with the existence of the abstract type in my assembly. Regardless, I discovered some issues with the behavior of child object definitions which are dicsussed below.
Section 3.5 of the reference document states:
the container's internal PreInstantiateSingletons method will completely ignore object definitions that don't have either a parent or class attribute set, since they are not complete."
Section 3.5 also states this:
An object definition explicitly can also be declared as abstract... this will prevent the object from being
instantiated (and any attempt to instantiate the object will result in an ObjectDefinitionIsAbstract exception
being thrown). Note also that XmlObjectFactory will by default pre-instantiate all singletons, but singleton
object definitions that have been declared as abstract will not be pre-instantiated.
These two statements seems to contradict each other.
I conducted four tests to verify Spring's behavior.
Given the following two classes:
public abstract class AbstractClass {
public AbstractClass() {
}
private string baseProperty;
public string BaseProperty {
get { return this.baseProperty; }
set { this.baseProperty = value; }
}
}
public class DerivedClass : AbstractClass {
public DerivedClass() {
}
private string childProperty;
public string ChildProperty {
get { return this.childProperty; }
set { this.childProperty = value; }
}
}
Test 1
<object name="AbstractClass" class="abstracts.AbstractClass, abstracts">
<property name="BaseProperty"><value>MyValue</value></property>
</object>
<object name="DerivedClass" class="abstracts.DerivedClass, abstracts" parent="AbstractClass">
<property name="ChildProperty"><value>MyOtherValue</value></property>
</object>
Results:
Error creating object with name 'AbstractClass' defined in '[Configuration File Section] : objects' : Initialization of object failed : Could not instantiate type [Void .ctor()]; is it an interface or an abstract class? Does it have a no-arg constructor?
This result is expected as the class listed is abstract.
Test 2
<object name="AbstractClass">
<property name="BaseProperty"><value>MyValue</value></property>
</object>
<object name="DerivedClass" class="abstracts.DerivedClass, abstracts" parent="AbstractClass">
<property name="ChildProperty"><value>MyOtherValue</value></property>
</object>
Results:
Object definition does not carry a resolved object class
This result contradicts the first statement. The object "AbstractClass" has neither a "parent" not a "class" attribute
Test 3
<object name="AbstractClass" class="abstracts.AbstractClass, abstracts" abstract="True">
<property name="BaseProperty"><value>MyValue</value></property>
</object>
<object name="DerivedClass" class="abstracts.DerivedClass, abstracts" parent="AbstractClass">
<property name="ChildProperty"><value>MyOtherValue</value></property>
</object>
Results:
Error creating object with name 'AbstractClass' defined in '[Configuration File Section] : objects' : Initialization of object failed : Could not instantiate type [Void .ctor()]; is it an interface or an abstract class? Does it have a no-arg constructor?
I expected "True" to be a valid option and Spring didn't complain. The DTD lists "true" and "false" as valid, I would expected all booleans to work (i.e. Any casing of True and False as well as 0 and 1.)
Test 4
<object name="AbstractClass" class="abstracts.AbstractClass, abstracts" abstract="true">
<property name="BaseProperty"><value>MyValue</value></property>
</object>
<object name="DerivedClass" class="abstracts.DerivedClass, abstracts" parent="AbstractClass">
<property name="ChildProperty"><value>MyOtherValue</value></property>
</object>
Results: Sucess! :)
The results of tests 2 & 3 were not consistent with my expectations.
Thanks,
Tom
P.S. Sorry this was so long....
Section 3.5 of the reference document states:
the container's internal PreInstantiateSingletons method will completely ignore object definitions that don't have either a parent or class attribute set, since they are not complete."
Section 3.5 also states this:
An object definition explicitly can also be declared as abstract... this will prevent the object from being
instantiated (and any attempt to instantiate the object will result in an ObjectDefinitionIsAbstract exception
being thrown). Note also that XmlObjectFactory will by default pre-instantiate all singletons, but singleton
object definitions that have been declared as abstract will not be pre-instantiated.
These two statements seems to contradict each other.
I conducted four tests to verify Spring's behavior.
Given the following two classes:
public abstract class AbstractClass {
public AbstractClass() {
}
private string baseProperty;
public string BaseProperty {
get { return this.baseProperty; }
set { this.baseProperty = value; }
}
}
public class DerivedClass : AbstractClass {
public DerivedClass() {
}
private string childProperty;
public string ChildProperty {
get { return this.childProperty; }
set { this.childProperty = value; }
}
}
Test 1
<object name="AbstractClass" class="abstracts.AbstractClass, abstracts">
<property name="BaseProperty"><value>MyValue</value></property>
</object>
<object name="DerivedClass" class="abstracts.DerivedClass, abstracts" parent="AbstractClass">
<property name="ChildProperty"><value>MyOtherValue</value></property>
</object>
Results:
Error creating object with name 'AbstractClass' defined in '[Configuration File Section] : objects' : Initialization of object failed : Could not instantiate type [Void .ctor()]; is it an interface or an abstract class? Does it have a no-arg constructor?
This result is expected as the class listed is abstract.
Test 2
<object name="AbstractClass">
<property name="BaseProperty"><value>MyValue</value></property>
</object>
<object name="DerivedClass" class="abstracts.DerivedClass, abstracts" parent="AbstractClass">
<property name="ChildProperty"><value>MyOtherValue</value></property>
</object>
Results:
Object definition does not carry a resolved object class
This result contradicts the first statement. The object "AbstractClass" has neither a "parent" not a "class" attribute
Test 3
<object name="AbstractClass" class="abstracts.AbstractClass, abstracts" abstract="True">
<property name="BaseProperty"><value>MyValue</value></property>
</object>
<object name="DerivedClass" class="abstracts.DerivedClass, abstracts" parent="AbstractClass">
<property name="ChildProperty"><value>MyOtherValue</value></property>
</object>
Results:
Error creating object with name 'AbstractClass' defined in '[Configuration File Section] : objects' : Initialization of object failed : Could not instantiate type [Void .ctor()]; is it an interface or an abstract class? Does it have a no-arg constructor?
I expected "True" to be a valid option and Spring didn't complain. The DTD lists "true" and "false" as valid, I would expected all booleans to work (i.e. Any casing of True and False as well as 0 and 1.)
Test 4
<object name="AbstractClass" class="abstracts.AbstractClass, abstracts" abstract="true">
<property name="BaseProperty"><value>MyValue</value></property>
</object>
<object name="DerivedClass" class="abstracts.DerivedClass, abstracts" parent="AbstractClass">
<property name="ChildProperty"><value>MyOtherValue</value></property>
</object>
Results: Sucess! :)
The results of tests 2 & 3 were not consistent with my expectations.
Thanks,
Tom
P.S. Sorry this was so long....