Let's say I have this class:
public class FooToBarTransformer {
public Bar transform(Foo foo) {
// do some cool stuff
}
}
And I want to consume it as a Function
in some other class:
public class Thing {
public Thing(Function<Foo, Bar> f) {
this.converter = f;
}
}
Now, if I'm instantiating a Thing
through Java, I'd do it with Java8 Lambdas like this:
FooToBarTransformer transformer = new FooToBarTransformer();
new Thing((foo) -> transformer.transform(foo));
// or new Thing(transformer::transform);
My problem, is that I need to create a Thing
though spring.
<bean id="fooToBarTransformer" class="com.mypackage.FooToBarTransformer"/>
<bean id="theThing" class="com.mypackage.Thing">
<constructor-arg index="0" ????????? />
</bean>
Now, there are a few possible workarounds I've considered to make this easier:
FooToBarTransformer
implemented Function
, then it would just be a simple ref="fooToBarTransformer"
FooToBarTransformer
implements and change Thing
to take an instance of that interface instead of Function
. For the purpose of this question, neither of those are options.Based on some other ways I've seen of doing executions in the spring xml, I've tried value="#{(foo) -> fooToBarTransformer.transform(foo)}"
and value="#{fooToBarTransformer::transform}"
but spring choked on this.
The best option I've come up with so far is to provide a translation function in code:
public Function<Foo, Bar> toFunction() {
return transformer::transform;
}
and reference it in spring with value="#{fooToBarTransformer.toFunction()}"
, but this seems rather hokey.
Is there a better way to do this?
I think what you need to do is to switch to Java Config (http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#beans-java) In the meantime, if you can't switch, you can still pull it off by combining methods. In you're XML configuration file add:
<bean class="com.myapp.config.FooBarConfiguration"/>
Then, you create class com.myapp.config.FooBarConfiguration
like this:
@Configuration
public class FooBarConfiguration {
@Bean
public FooToBarTransformer fooTransformer() {
return new FooToBarTransformer();
}
@Bean
public Thing theThing(FooToBarTransformer fooTransformer) {
return new Thing(fooTransformer::transform);
}
}
Just make sure that ConfigurationClassPostProcessor
is a registered post-processor in your Spring context by either having:
<context:annotation-config>
Or
<context:component-scan>
Or by manually adding the post processor as a bean:
<bean class="org.springframework.context.annotation.ConfigurationClassPostProcessor"/>
This should work from Spring 3.0 and above according with http://docs.spring.io/spring/docs/current/javadoc-api/index.html?org/springframework/context/annotation/ConfigurationClassPostProcessor.html. Not sure what version you're using.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With