Alex Rivera | Logout

How to make Spring accept fluent (non-void) setters?

Asked 2010-05-24T23:54:33.803
14

I have an API which I am turning into an internal DSL. As such, most methods in my PoJos return a reference to this so that I can chain methods together declaratively as such (syntactic sugar).

myComponent
    .setID("MyId")
    .setProperty("One")
    .setProperty2("Two")
    .setAssociation(anotherComponent)
    .execute();

My API does not depend on Spring but I wish to make it 'Spring-Friendly' by being PoJo friendly with zero argument constructors, getters and setters. The problem is that Spring seems to not detect my setter methods when I have a non-void return type.

The return type of this is very convenient when chaining together my commands so I don't want to destroy my programmatic API just be to compatible with Spring injection.

Is there a setting in Spring to allow me to use non-void setters?

Chris

Edit
Report

1 Answer

7

Spring can also be configured with Java configuration.

An example:

@Configuration
public class Config {
    @Bean
    public MyComponent myComponent() {
        return MyComponent
            .setID(id)
            .setProperty("One", "1")
            .setProperty("Two", "2")
            .setAssociation(anotherConfig.anotherComponent())
            .execute();
    }

    @Autowired
    private AnotherConfig anotherConfig;

    @Value("${id}")
    private String id;
}

You have a nice immutable object. You have actually implemented the Builder pattern!

Updated to respond to Chris's comment:

I guess it's not exactly what you want, but using properties files solves some issues. See the id field in the example above.

Else, you can use Spring's FactoryBean pattern:

public class MyComponentFactory implements FactoryBean<MyComponent> {

    private MyComponent myComponent;

    public MyComponentFactory(String id, Property propertyOne, ..) {
        myComponent = MyComponent
            .setID(id)
            .setProperty("One", "1")
            .set(..)
            .execute();
    }

    public MyComponent getObject() throws Exception {
        return myComponent;
    }

    public Class<MyComponent> getObjectType() {
        return MyComponent.class;
    }

    public boolean isSingleton() {
        return false;
    }
}

With the FactoryBean, you shield the configuration from the object returned from the getObject() method.

In the XML configuration, you configure the FactoryBean implementation. In this case with <constructor

answered 2010-05-25T00:09:29.527

Your Answer