简体   繁体   English

在Spring XML中使用Java8 Lambda函数

[英]Using a Java8 Lambda Function inside spring XML

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: 我想在其他一些类中将其作为Function使用:

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: 现在,如果要通过Java实例化Thing ,则可以使用Java8 Lambda来实现,如下所示:

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 . 我的问题是我需要通过spring创建一个Thing

<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: 现在,我考虑了一些可能的解决方法来简化此工作:

  1. if FooToBarTransformer implemented Function , then it would just be a simple ref="fooToBarTransformer" 如果FooToBarTransformer实现了Function ,那么它将只是一个简单的ref="fooToBarTransformer"
  2. I could create a different interface that FooToBarTransformer implements and change Thing to take an instance of that interface instead of Function . 我可以创建一个由FooToBarTransformer实现的不同接口, FooToBarTransformer Thing更改为采用该接口的实例而不是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. 基于我在spring xml中执行执行的其他方式,我尝试了value="#{(foo) -> fooToBarTransformer.transform(foo)}"value="#{fooToBarTransformer::transform}"但是春天对此感到窒息。

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. 并在春季使用value="#{fooToBarTransformer.toFunction()}"引用它,但这似乎很粗鲁。

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. 我认为您需要做的是切换到Java Config( http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#beans-java )同时,如果可以的话不要切换,您仍然可以通过组合方法来实现。 In you're XML configuration file add: 在您的XML配置文件中,添加:

<bean class="com.myapp.config.FooBarConfiguration"/>

Then, you create class com.myapp.config.FooBarConfiguration like this: 然后,您像这样创建类com.myapp.config.FooBarConfiguration

@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: 只需通过以下任一方法确保ConfigurationClassPostProcessor在您的Spring上下文中是注册的后处理器:

<context:annotation-config>

Or 要么

<context:component-scan>

Or by manually adding the post processor as a bean: 或通过手动将后处理器添加为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 . 根据http://docs.spring.io/spring/docs/current/javadoc-api/index.html?org/springframework/context/annotation/ConfigurationClassPostProcessor.html,这应该从Spring 3.0及更高版本开始。 Not sure what version you're using. 不确定您使用的是哪个版本。

Try to use factory pattern. 尝试使用工厂模式。 See org.springframework.beans.factory.FactoryBean. 参见org.springframework.beans.factory.FactoryBean。 Also spring has expression language. spring也有表达语言。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM