tags:

views:

248

answers:

3

I read about Compound property names in the "The Spring Framework (2.5) - Reference Documentation - chapter 3.3.2.7"

Can i use the same concept to set values of properties? Can i use a compound string as a value expression?

<bean id="service1" class="a.b.c.Service1Impl" scope="prototype">
   <property name="service2" ref="service2"/>
   <property name="service2.user" value="this-service1-instance.user"/> 
</bean>
<bean id="service2" class="a.b.c.Service2Impl" scope="prototype">
    ... 
</bean>

User is a property of a.b.c.Service1Impl which is not in control of Spring. I want to forward this property to a.b.c.Service2Impl.

A: 

Spring's XML wiring syntax supports lists, maps and properties objects, and you can create other 'data' objects via property editors.

Edit: (Oh I see what you are asking.) I think that the answer is no. I don't recall having seen any mention of calling getters on a bean or non-bean object in the Spring documentation, let alone a syntax for doing this in the wiring file. It tends to go against the grain. Spring wiring is declarative, and calling a getter would lead to patterns that are bordering on procedural.

Stephen C
+1  A: 

I had to do something similar, and I'm afraid it's not possible. I had to write a [FactoryBean][1] to expose the property.

It would look something like this:

public class UserFactory implements BeanFactory {
    private Service2 service2;
    // ... setter and getter for service2

    public Object getObject() {
        return getService2().getUser();
    }

    public Class getObjectType() {
        return User.class;
    }

    public boolean isSingleton() {
        // Since it's a prototype in your case
        return false;
    }
}

Come to think of it, in your case, you'd probably define the factory itself as a prototype, in which case your isSingleton() may return true, you'll need to play around with this a little bit.

Jack Leow
+2  A: 

Rather than use a plain old factory bean, rather use a factory method to create the bean of the property and then inject that result...

iow

in your case, it would look something like this...

<!-- the bean to be created via the factory bean -->
<bean id="exampleBean"
      factory-bean="serviceLocator"
      factory-method="createInstance"/>

So the bean of id is created by calling createInstance on bean serviceLocator.

Now spring does not support nested properties out of the box, though you could look at creating a custom editors which might provide that support - possible but tricky. Possibly not worth the effort.

One mechanism you could look at using is nesting using the factory-bean factory-method technique...

Something like:

<bean id="c" class="C" />
<bean id="b" factory-bean="c" factory-method="getB"/>
<bean id="a" factory-bean="b" factory-method="getA"/>

This will effectively expose: a.b.c where C has a method getB and A has a method getB

Michael Wiles
I suck at life, this is much better.
Jack Leow