View Full Version : PropertyPlaceholderConfigurer for bean class
bpryor
Oct 19th, 2004, 03:22 PM
I have just started to use Spring in a Tapestry web application. I'm currently making heavy use of Tapestry "extensions" which are managed objects just like Spring beans upon which properties can be set.
I am planning on using the Spring stack to eliminate these Tapestry extensions, making the service objects into Spring beans. The initial target use of Spring then is as a simple service manager / locator.
The application is heavily customized - a common idiom we use is to have an interface with a different concrete implementation for each client.
So what I really wanted to do was:
<bean id="serviceBean" class="${client.service.class}" />
... and use the PropertyPlaceholderConfigurer to replace the token with the actual name of the concrete service class for a client.
However, it seems that the PropertyPlaceholderConfigurer is useful only for replacing <property> values, which makes sense given its name.
Is there a better way to accomplish this using Spring?
An additional note: I would like to have a single applicationContext.xml file - each client would have their own client.properties with customized values.
irbouho
Oct 19th, 2004, 03:40 PM
try the following:
<bean id="serviceBean" class="java.lang.Class" factory-method="forName">
<constructor-arg>
<value>${client.service.class}</value>
</constructor-arg>
</bean>
HTH
bpryor
Oct 19th, 2004, 04:07 PM
Thanks for the suggestion. That does almost what I'm looking for, except that the service bean ends up being a java.lang.Class instead of an instance of that class. Using that idea, I found that something like this works:
<bean id="serviceFactory" class="java.lang.Class" factory-method="forName" singleton="false">
<constructor-arg><value>${client.service.class}</value></constructor-arg>
</bean>
<bean id="serviceBean" factory-bean="serviceFactory" factory-method="newInstance" />
Is there a way to accomplish this with a single <bean> declaration?
jbetancourt
Oct 19th, 2004, 06:28 PM
The most direct route is not possible. I don't think Spring allows migration of bean attributes to elements so that an inline bean definitions could be used here, but maybe that would be useful in many other situations. [not implying this is what you are looking for, of course].
Not possible?
<bean id="serviceBean" factory-method="newInstance">
<property name="factory-bean">
<bean class="java.lang.Class" factory-method="forName" singleton="false">
<constructor-arg><value>${client.service.class}</value></constructor-arg>
</bean>
</property>
</bean>
Thanks for the suggestion. That does almost what I'm looking for, except that the service bean ends up being a java.lang.Class instead of an instance of that class. Using that idea, I found that something like this works:
<bean id="serviceFactory" class="java.lang.Class" factory-method="forName" singleton="false">
<constructor-arg><value>${client.service.class}</value></constructor-arg>
</bean>
<bean id="serviceBean" factory-bean="serviceFactory" factory-method="newInstance" />
Is there a way to accomplish this with a single <bean> declaration?
cmgharris
Oct 20th, 2004, 02:35 AM
You could write your own factory bean class, e.g. ClassInstantiatingFactoryBean, implementing FactoryBean and having the class name as a property.
Then you'd get your instance with
<bean id="serviceBean" class="foo.bar.ClassInstantiatingFactoryBean">
<property name="className"><value>${client.service.class}</value></property>
</bean>
.NET Guy
Oct 20th, 2004, 02:46 AM
How about this approach? It does mean writing some code though :?
public class Activator {
public static object createInstance (string clazz) {
return Activator.createInstance (Class.forName (clazz));
}
public static object createInstance (Class clazz) {
return clazz.newInstance ();
}
}
<bean id="serviceBean" class="Activator" factory-method="createInstance">
<constructor-arg>
<value>${client.service.class}</value>
</constructor-arg>
</bean>
I have (obviously) left out all error checking, etc :wink:
bpryor
Oct 20th, 2004, 08:20 AM
Thanks for all the suggestions. I ended up writing a simple class instantiator factory that does a Class.forName and a newInstance() based off a className argument. I used a single bean declaration with factory-method, passing in the className as a constructor-arg.
This approach allows me to set properties on the created beans as well as specify their class.
Powered by vBulletin® Version 4.2.1 Copyright © 2013 vBulletin Solutions, Inc. All rights reserved.