在Spring中传递属性文件中的bean ID

时间:2017-08-07 09:55:44

标签: spring spring-integration

我有一个springboot应用程序,它使用spring集成在几个组件之间路由tcp消息,它可以从功能POV中正常工作。我一直试图清理代码并用属性文件中声明的常量替换多个硬编码值(通道名称):

实际示例包含多个频道和路由器:

<int:channel id="input">

<int:channel id="outputA"/>
<int:channel id="outputB"/>
<int:channel id="outputC"/>

<int:router method="determineTargetChannel" input-channel="input">
    <beans:bean class="MyRouter"/>
</int:router>

和MyRouter类:

@Component
public class MyRouter {

    @Router
    public String determineTargetChannel(Object payload) {
        if (condition1) {
            return "outputA";
        } else if (condition2) {
            return "outputB";
        } else return "outputC";
    }    
}

我不希望在两个地方硬编码通道ID,包括XML文件和Router类(或任何其他可以将它们作为常量保存的类)。

所以我尝试了以下内容:

1)将ID存储在属性YML文件中:

router:
    channel:
        outputA: outputA
        outputB: outputB
        outputC: outputC

2)更新XML文件:

<int:channel id="input">

<int:channel id="${router.channel.outputA}"/>
<int:channel id="${router.channel.outputB}"/>
<int:channel id="${router.channel.outputC}"/>

<int:router method="determineTargetChannel" input-channel="input">
    <beans:bean class="MyRouter"/>
</int:router>

3)更新MyRouter类:

@Component
public class DARouter {

    @Value("${router.channel.outputA}")
    private String outputA;

    @Value("${router.channel.outputB}")
    private String outputB;

    @Value("${router.channel.outputC}")
    private String outputC;

    @Router
    public String determineTargetChannel(Object payload) {
        if (condition1) {
            return outputA;
        } else if (condition2) {
            return outputB;
        } else return outputC;
    }
}

问题是,当Spring创建XML文件中声明的bean时,它不解析属性值,因此它创建一个ID = $ {router.channel.outputA的bean而不是实际值outputA。

这不是不加载属性文件的问题,因为如果我尝试将属性传递给其他字段(而不是bean ID),它可以正常工作并正确注入值,例如:

<int:router method="determineTargetChannel" input-channel="${router.channel.outputA}">
    <beans:bean class="MyRouter"/>
</int:router>

1 个答案:

答案 0 :(得分:3)

这就是Spring的工作方式。 id只能静态声明。这就是&#39; @ Bean`的Java配置基于方法名称的方式,我们无法在外部指定方法名称。只是因为它已经编译。

您应该重新考虑您的设计以保持当前的功能。