joeslice
joeslice

Reputation: 3464

Generate Spring bean definition from a Java object

Let's suggest that I have a bean defined in Spring:

<bean id="neatBean" class="com..." abstract="true">...</bean>

Then we have many clients, each of which have slightly different configuration for their 'neatBean'. The old way we would do it was to have a new file for each client (e.g., clientX_NeatFeature.xml) that contained a bunch of beans for this client (these are hand-edited and part of the code base):

<bean id="clientXNeatBean" parent="neatBean">
    <property id="whatever" value="something"/>
</bean>

Now, I want to have a UI where we can edit and redefine a client's neatBean on the fly.

My question is: given a neatBean, and a UI that can 'override' properties of this bean, what would be a straightforward way to serialize this to an XML file as we do [manually] today?

For example, if the user set property whatever to be "17" for client Y, I'd want to generate:

<bean id="clientYNeatBean" parent="neatBean">
    <property id="whatever" value="17"/>
</bean>

Note that moving this configuration to a different format (e.g., database, other-schema'd-xml) is an option, but not really an answer to the question at hand.

Upvotes: 4

Views: 5109

Answers (6)

Olivier Croisier
Olivier Croisier

Reputation: 6149

What you need is obviously a factory for your neatBeans.

In Spring, instead of declaring a bean, you can declare a FactoryBean whose role is to actually create and configure your final bean. The NeatBeanFactoryBean could read a property file (or xml configuration) to determine how to configure the produced neatBeans, depending on some runtime parameter (the current clientID for example) or compile-time parameter (environment variable).

Upvotes: 2

Peter Tillemans
Peter Tillemans

Reputation: 35341

If you want a simple to implement, no work solution, you can look at the IDE support provided in IntelliJ and Eclipse (The Spring Tool Suite).

They parse all the bean files (you can configure which set) and inspect the java code so it knows which classes there are, which properties are in those classes. Everywhere you can use Ctrl-Space to help with the options, etc...

I imagine you could setup 'projects' w/o Java code and only the spring config files in order to reduce the learning curve of front line personnel who must make these changes.

Upvotes: 3

Bozho
Bozho

Reputation: 597314

I'd suggest using

<context:property-placeholder location="classpath*:clientX.properties"/>

and then in your bean def:

<bean id="${clientYNeatBeanId}" parent="neatBean">
    <property id="whatever" value="${whateverValue}"/>
</bean>

Then for each client you can have a clientX.properties containing

whateverValue=17
whateverAnotherValue=SomeText

.properties files are easier to edit both manually, and programaticalyl via java.util.Properties store(..) / save(..) methods

Upvotes: 1

alex
alex

Reputation: 5201

To add to the other two questions, I believe Spring already has a working model for bean definitions (see org.springframework.beans.factory.config.BeanDefinition); you could base your work on that.

Upvotes: 1

Abhinav Sarkar
Abhinav Sarkar

Reputation: 23812

You can download the Spring-beans 2.5 xsd from here and run xjc on it to generate the Java classes with JAXB bindings. Then you can create the Spring-beans object hierarchy on runtime (and manipulate it as you wish) and then serialize it to an XML string using the JAXB Marshaller as shown in Pablojim's answer.

Upvotes: 7

Pablojim
Pablojim

Reputation: 8582

I'd use Jax-b to do this. You'de create a bean object with a list of property objects inside.

@XmlRootElement(name = "bean")
@XmlAccessorType(XmlAccessType.FIELD)

public class Bean {

  @XmlAttribute
  private String id;
  @XmlAttribute
  private String parent;

  @XmlElement(name="property")
  private List<BeanProperty> properties

Then You'd need to also add annotations to BeanProperty. Then when you have a populated object simply marshal it to xml using jaxb:

Marshaller m = jc.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
m.marshal( myBean, System.out );

For full code examples see: http://java.sun.com/webservices/docs/2.0/tutorial/doc/JAXBUsing.html

Alternatively you could use Groovy - you can drop it in place and creating this xml would be very simple... : http://www.ibm.com/developerworks/java/library/j-pg05199/index.html

Upvotes: 3

Related Questions