In most cases, you can use the <value> element to pass a simple type into a Spring bean. For example
<bean id="validator" class="pkg.ValidatorImpl">
<constructor-arg index="0">
<property name="className" value="pkg.DomainClass" />
</constructor-arg>
</bean>
If the class doesn't support a simple type, like String in the previous example, you'll either need to expand the constructor definition to allow for a String or use a different Spring configuration based on MethodInvokingFactoryBean.
This example wraps up the Class.forName() call into a nested Spring bean. "staticMethod" is a fully-qualified method name. "arguments" is an ordered list of arguments for the static method. The Spring-provided MethodInvokingFactoryBean is used to control the invoking.
<bean id="validator" class="pkg.ValidatorImpl">
<constructor-arg index="0">
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="staticMethod">
<value>java.lang.Class.forName</value>
</property>
<property name="arguments">
<list>
<value>pkg.DomainClass</value>
</list>
</property>
</bean>
</constructor-arg>
</bean>
Using simple types in your bean's definition constructor makes configuring the beans easier. However, if you aren't able to expand the bean's constructors -- say it's from a third party library -- take a factory approach.
Hi, Thank you for the useful information.
ReplyDeleteI have one doubt regd. "pkg.DomainClass" - What if the package "pkg" is defined in a different project? Can Spring will be able to locate that "DomainClass" since it is not annotated with @bean?
Thank you
Hi,
Deletepkg.DomainClass is not a Spring bean class, but a .class file that appears on the classpath. This is a workaround for non-Java Bean classes, in this case java.lang.Class which doesn't have a default constructor.
Thanks, nice tip
ReplyDelete