2.7. attribute Placeholders


概述

属性占位符功能可用于将字符串替换为不同的上下文(如 XML DSL 元素中的端点 URI 和属性),其中占位符设置存储在 Java 属性文件中。如果您要在不同 Apache Camel 应用程序间共享设置,或者您想要集中特定的配置设置,则这个功能很有用。

例如,以下路由将请求发送到 Web 服务器(其主机和端口由占位符替换)、{{remote.host}}{{remote.port}}

from("direct:start").to("http://{{remote.host}}:{{remote.port}}");
Copy to Clipboard Toggle word wrap

占位符值在 Java 属性文件中定义,如下所示:

# Java properties file
remote.host=myserver.com
remote.port=8080
Copy to Clipboard Toggle word wrap
注意

属性 Placeholders 支持编码选项,可让您使用特定的字符集(如 UTF-8)读取 .properties 文件。但是,默认情况下,它会实施 ISO-8859-1 字符集。

使用 PropertyPlaceholders 的 Apache Camel 支持以下内容:

  • 将默认值与要查找的键一起指定。
  • 不需要定义 PropertiesComponent,如果所有占位符键都包含默认值,则会使用它们。
  • 使用第三方函数查找属性值。它可让您实施自己的逻辑。

    注意

    提供三个开箱即用功能,以从 OS 环境变量、JVM 系统属性或服务名称 idiom 查找值。

属性文件

属性设置存储在一个或多个 Java 属性文件中,且必须符合标准的 Java 属性文件格式。每个属性设置出现在其自己的行中,格式为 Key=Value。带有 #! 作为第一个非空字符的行被视为注释。

例如,属性文件可能含有内容,如 例 2.4 “Property 文件示例” 所示。

例 2.4. Property 文件示例

# Property placeholder settings
# (in Java properties file format)
cool.end=mock:result
cool.result=result
cool.concat=mock:{{cool.result}}
cool.start=direct:cool
cool.showid=true

cheese.end=mock:cheese
cheese.quote=Camel rocks
cheese.type=Gouda

bean.foo=foo
bean.bar=bar
Copy to Clipboard Toggle word wrap

解决属性

属性组件必须配置有一个或多个属性文件的位置,然后才能在路由定义中使用它。您必须使用以下解析器之一提供属性值:

classpath:PathName,PathName,…​
(默认) 指定类路径中的位置,其中 PathName 是使用正斜杠分隔的文件路径名。
file:PathName,PathName,…​
指定文件系统中的位置,其中 PathName 是以正斜杠分隔的文件路径名。
ref:BeanID
指定 registry 中的 java.util.Properties 对象的 ID。
蓝图:BeanID
指定 cm:property-placeholder bean 的 ID,该 ID 可用于访问 OSGi 配置管理服务中定义的属性。详情请查看 “与 OSGi 蓝图属性占位符集成”一节

例如,要指定 com/fusesource/cheese.properties 属性文件和 com/fusesource/bar.properties 属性文件,两者均位于 classpath 上,您需要使用以下位置字符串:

com/fusesource/cheese.properties,com/fusesource/bar.properties
Copy to Clipboard Toggle word wrap
注意

您可以省略本例中的 classpath: 前缀,因为默认情况下使用 classpath 解析器。

使用系统属性和环境变量指定位置

您可以在位置 PathName 中嵌入 Java 系统属性和 O/S 环境变量。

Java 系统属性可以使用语法 ${PropertyName} 嵌入在位置解析器中。例如,如果 Red Hat Fuse 的根目录存储在 Java 系统属性 karaf.home 中,您可以把该目录值嵌入到文件位置中,如下所示:

file:${karaf.home}/etc/foo.properties
Copy to Clipboard Toggle word wrap

O/S 环境变量可以使用语法( ${env:VarName} )嵌入到位置解析器中。例如,如果 JBoss Fuse 的根目录存储在环境变量 SMX_HOME 中,您可以将该目录的内容嵌入到文件位置,如下所示:

file:${env:SMX_HOME}/etc/foo.properties
Copy to Clipboard Toggle word wrap

配置属性组件

在开始使用属性占位符前,您必须配置属性组件,指定一个或多个属性文件的位置。

在 Java DSL 中,您可以使用属性文件位置配置属性组件,如下所示:

// Java
import org.apache.camel.component.properties.PropertiesComponent;
...
PropertiesComponent pc = new PropertiesComponent();
pc.setLocation("com/fusesource/cheese.properties,com/fusesource/bar.properties");
context.addComponent("properties", pc);
Copy to Clipboard Toggle word wrap

addComponent() 调用所示,属性组件的名称 必须设置为 属性

在 XML DSL 中,您可以使用专用 propertyPlacholder 元素配置属性组件,如下所示:

<camelContext ...>
   <propertyPlaceholder
      id="properties"
      location="com/fusesource/cheese.properties,com/fusesource/bar.properties"
   />
</camelContext>
Copy to Clipboard Toggle word wrap

如果您希望属性组件在初始化时忽略任何缺少的 .properties 文件,您可以将 ignoreMissingLocation 选项设置为 true (通常情况下,缺少 .properties 文件会导致错误引发)。

另外,如果您希望属性组件忽略使用 Java 系统属性或 O/S 环境变量指定的任何缺少的位置,您可以将 ignoreMissingLocation 选项设置为 true

占位符语法

配置后,属性组件会自动替换占位符(在适当的上下文中)。占位符语法取决于上下文,如下所示:

  • 在端点 URI 中,在 Spring XML 文件中 InventoryService-","the 占位符被指定为 { {Key}}
  • 当设置 XML DSL 属性时 ,使用以下语法设置 字符串 属性:

    AttributeName="{{Key}}"
    Copy to Clipboard Toggle word wrap

    必须使用以下语法设置其他属性类型(例如 xs:intxs:boolean):

    prop:AttributeName="Key"
    Copy to Clipboard Toggle word wrap

    其中 prophttp://camel.apache.org/schema/placeholder 命名空间关联。

  • 在设置 Java DSL EIP 选项 targetNamespaces 选项 InventoryService-jaxbto 时,在 Java DSL 中对企业级集成模式(EIP)命令设置选项时,请在流畅的 DSL 中添加类似于以下内容的 占位符() 子句:

    .placeholder("OptionName", "Key")
    Copy to Clipboard Toggle word wrap
  • 在简单语言表达式中 ,placeholder指定为 ${properties:Key}

在端点 URI 中替换

只要端点 URI 字符串出现在路由中,解析端点 URI 的第一步是应用属性占位符解析器。占位符解析器自动替换双花括号之间出现的任何属性名称 {{ Key}}。例如,如果 例 2.4 “Property 文件示例” 中显示的属性设置,您可以定义路由,如下所示:

from("{{cool.start}}")
    .to("log:{{cool.start}}?showBodyType=false&showExchangeId={{cool.showid}}")
    .to("mock:{{cool.result}}");
Copy to Clipboard Toggle word wrap

默认情况下,占位符解析器查找 registry 中的 属性 bean ID 来查找属性组件。如果愿意,您可以在端点 URI 中明确指定方案。例如,通过为每个端点 URI 加上前缀 属性: 到每个端点 URI,您可以定义以下等同的路由:

from("properties:{{cool.start}}")
    .to("properties:log:{{cool.start}}?showBodyType=false&showExchangeId={{cool.showid}}")
    .to("properties:mock:{{cool.result}}");
Copy to Clipboard Toggle word wrap

在明确指定方案时,您还可以选择指定属性组件的选项。例如,要覆盖属性文件位置,您可以按照如下所示设置 location 选项:

from("direct:start").to("properties:{{bar.end}}?location=com/mycompany/bar.properties");
Copy to Clipboard Toggle word wrap

在 Spring XML 文件中替换

您还可以使用 XML DSL 中的属性占位符,设置 DSL 元素的各种属性。在此上下文中,拥有者语法也使用双花括号 {{ Key}}。例如,您可以使用属性占位符定义 jmxAgent 元素,如下所示:

<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
    <propertyPlaceholder id="properties" location="org/apache/camel/spring/jmx.properties"/>

    <!-- we can use property placeholders when we define the JMX agent -->
    <jmxAgent id="agent" registryPort="{{myjmx.port}}"
              usePlatformMBeanServer="{{myjmx.usePlatform}}"
              createConnector="true"
              statisticsLevel="RoutesOnly"
            />

    <route>
        <from uri="seda:start"/>
        <to uri="mock:result"/>
    </route>
</camelContext>
Copy to Clipboard Toggle word wrap

替换 XML DSL 属性值

您可以使用常规占位符语法来指定 xs:string typegradle-sHistoryLimitfor example, < jmxAgent registryPort="{{myjmx.port}}" …​ >。但是,对于任何其他类型的属性(例如,xs:intxs:boolean),您必须使用特殊语法 prop:AttributeName="Key"

例如,如果某个属性文件定义了 stop.flag 属性的值为 true,您可以使用此属性来设置 stopOnException 布尔值属性,如下所示:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:prop="http://camel.apache.org/schema/placeholder"
       ... >

    <bean id="illegal" class="java.lang.IllegalArgumentException">
        <constructor-arg index="0" value="Good grief!"/>
    </bean>

    <camelContext xmlns="http://camel.apache.org/schema/spring">

        <propertyPlaceholder id="properties"
                             location="classpath:org/apache/camel/component/properties/myprop.properties"
                             xmlns="http://camel.apache.org/schema/spring"/>

        <route>
            <from uri="direct:start"/>
            <multicast prop:stopOnException="stop.flag">
                <to uri="mock:a"/>
                <throwException ref="damn"/>
                <to uri="mock:b"/>
            </multicast>
        </route>

    </camelContext>

</beans>
Copy to Clipboard Toggle word wrap
重要

必须明确分配给 Spring 文件中的 http://camel.apache.org/schema/placeholder 命名空间,如上例的 Bean 元素中所示。

替换 Java DSL EIP 选项

在 Java DSL 中调用 EIP 命令时,您可以通过添加表单、占位符(" options Name", "Key") 值,使用属性值来设置任何 EIP 选项。

例如,如果某个属性文件定义了 stop.flag 属性的值为 true,您可以使用此属性设置多播 EIP 的 stopOnException 选项,如下所示:

from("direct:start")
    .multicast().placeholder("stopOnException", "stop.flag")
        .to("mock:a").throwException(new IllegalAccessException("Damn")).to("mock:b");
Copy to Clipboard Toggle word wrap

使用简单语言表达式替换

您还可以使用简单语言表达式替换属性占位符,但在本例中,占位符语法为 ${properties:Key}。例如,您可以替换简单表达式内的 cheese.quote 占位符,如下所示:

from("direct:start")
    .transform().simple("Hi ${body} do you think ${properties:cheese.quote}?");
Copy to Clipboard Toggle word wrap

您可以使用语法 ${properties:Key:DefaultVal} 来指定属性的默认值。例如:

from("direct:start")
    .transform().simple("Hi ${body} do you think ${properties:cheese.quote:cheese is good}?");
Copy to Clipboard Toggle word wrap

也可以使用语法( ${properties-location:Location:Key} )覆盖属性文件的位置。例如,要使用 com/mycompany/bar.properties 属性中的设置替换 bar.quote 占位符,您可以按照如下所示定义简单表达式:

from("direct:start")
    .transform().simple("Hi ${body}. ${properties-location:com/mycompany/bar.properties:bar.quote}.");
Copy to Clipboard Toggle word wrap

在 XML DSL 中使用 Property Placeholders

在旧版中,xs:string 类型属性用于支持 XML DSL 中的占位符。例如,timeout 属性是一个 xs:int 类型。因此,您无法将字符串值设置为占位符键。

从 Apache Camel 2.7 开始,现在可以使用特殊的占位符命名空间来实现。以下示例演示了命名空间的 prop 前缀。它允许您使用 XML DSL 中属性中的 prop 前缀。

注意

在多播中,将选项 stopOnException 设置为带有键 stop 的占位符值。另外,在属性文件中,将值定义为

stop=true
Copy to Clipboard Toggle word wrap
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:prop="http://camel.apache.org/schema/placeholder"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
    ">

    <!-- Notice in the declaration above, we have defined the prop prefix as the Camel placeholder namespace -->

    <bean id="damn" class="java.lang.IllegalArgumentException">
        <constructor-arg index="0" value="Damn"/>
    </bean>

    <camelContext xmlns="http://camel.apache.org/schema/spring">

        <propertyPlaceholder id="properties"
                             location="classpath:org/apache/camel/component/properties/myprop.properties"
                             xmlns="http://camel.apache.org/schema/spring"/>

        <route>
            <from uri="direct:start"/>
            <!-- use prop namespace, to define a property placeholder, which maps to
                 option stopOnException={{stop}} -->
            <multicast prop:stopOnException="stop">
                <to uri="mock:a"/>
                <throwException ref="damn"/>
                <to uri="mock:b"/>
            </multicast>
        </route>

    </camelContext>

</beans>
Copy to Clipboard Toggle word wrap

与 OSGi 蓝图属性占位符集成

如果您将路由部署到红帽 Fuse OSGi 容器中,您可以将 Apache Camel 属性占位符机制与 JBoss Fuse 的蓝图属性占位符机制(事实上是启用集成)。设置集成的基本方法有两种,如下所示:

隐式蓝图集成

如果您在 OSGi 蓝图文件中定义了 camelContext 元素,Apache Camel 属性占位符机制会自动与蓝图属性占位符机制集成。也就是说,在 camelContext 范围内出现的占位符遵循 Apache Camel 语法(如 {{cool.end}})通过查找 蓝图属性占位符 机制来隐式解析。

例如,考虑在 OSGi 蓝图文件中定义以下路由,路由中最后一个端点由属性占位符定义,{{result}}

<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.0.0"
           xsi:schemaLocation="
           http://www.osgi.org/xmlns/blueprint/v1.0.0 https://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">

    <!-- OSGI blueprint property placeholder -->
    <cm:property-placeholder id="myblueprint.placeholder" persistent-id="camel.blueprint">
        <!-- list some properties for this test -->
        <cm:default-properties>
            <cm:property name="result" value="mock:result"/>
        </cm:default-properties>
    </cm:property-placeholder>

    <camelContext xmlns="http://camel.apache.org/schema/blueprint">
        <!-- in the route we can use {{ }} placeholders which will look up in blueprint,
             as Camel will auto detect the OSGi blueprint property placeholder and use it -->
        <route>
            <from uri="direct:start"/>
            <to uri="mock:foo"/>
            <to uri="{{result}}"/>
        </route>
    </camelContext>

</blueprint>
Copy to Clipboard Toggle word wrap

蓝图属性占位符机制通过创建一个 cm:property-placeholder an 初始化。在前面的示例中,cm:property-placeholder bean 与 camel.blueprint 持久 ID 关联,持久 ID 是引用 OSGi 配置管理 服务中一组相关属性的标准方式。换句话说,cm:property-placeholder an 提供了对 camel.blueprint 持久 ID 中定义的所有属性的访问权限。也可以为某些属性指定默认值(使用嵌套的 cm:property 元素)。

在蓝图上下文中,Apache Camel 占位符机制搜索 bean registry 中的 cm:property-placeholder 实例。如果找到这样的实例,它会自动集成 Apache Camel 占位符机制,以便等占位符 {{result}} 可以通过在蓝图属性占位符机制中查找密钥(在这个示例中,通过 myblueprint.placeholder bean)来解决。

注意

默认蓝图占位符语法(直接访问蓝图属性)为 ${Key}。因此,在 camelContext 元素的范围 之外,您必须使用占位符语法为 ${Key}。但在 camelContext 元素的范围中,您必须使用占位符语法是 {{ Key}}

显式蓝图集成

如果您想要更多控制 Apache Camel 属性占位符机制在什么位置找到其属性,您可以定义一个 propertyPlaceholder 元素并明确指定解析器位置。

例如,请考虑以下与前面示例不同的蓝图配置,它会创建一个显式 propertyPlaceholder 实例:

<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.0.0"
           xsi:schemaLocation="
           http://www.osgi.org/xmlns/blueprint/v1.0.0 ">https://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">

    <!-- OSGI blueprint property placeholder -->
    <cm:property-placeholder id="myblueprint.placeholder" persistent-id="camel.blueprint">
        <!-- list some properties for this test -->
        <cm:default-properties>
            <cm:property name="result" value="mock:result"/>
        </cm:default-properties>
    </cm:property-placeholder>

    <camelContext xmlns="http://camel.apache.org/schema/blueprint">

        <!-- using Camel properties component and refer to the blueprint property placeholder by its id -->
        <propertyPlaceholder id="properties" location="blueprint:myblueprint.placeholder"/>

        <!-- in the route we can use {{ }} placeholders which will lookup in blueprint -->
        <route>
            <from uri="direct:start"/>
            <to uri="mock:foo"/>
            <to uri="{{result}}"/>
        </route>

    </camelContext>

</blueprint>
Copy to Clipboard Toggle word wrap

在前面的示例中,propertyPlaceholder 元素指定通过将位置设置为 blueprint:myblueprint.placeholder 来指定使用哪个 cm:property-placeholder。该 蓝图: 解析器明确引用 cm:property-placeholder 的 ID、myblueprint.placeholder

这种配置方式很有用,如果蓝图文件中定义了多个 cm:property-placeholder an,并且您需要指定要使用的选项。它还可通过指定以逗号分隔的位置列表,从多个位置的源属性。例如,如果要从 cm:property-placeholder bean 和 properties 文件( myproperties.properties )在 classpath 上查找属性,您可以按照如下所示定义 propertyPlaceholder 元素:

<propertyPlaceholder id="properties"
  location="blueprint:myblueprint.placeholder,classpath:myproperties.properties"/>
Copy to Clipboard Toggle word wrap

与 Spring 属性占位符集成

如果您在 Spring XML 文件中使用 XML DSL 定义 Apache Camel 应用程序,您可以通过声明类型为 Spring 片段机制来将 Apache Camel 属性占位符机制集成,org.apache.camel.spring.spi.BridgePropertyPlaceholderConfigurer

定义 BridgePropertyPlaceholderConfigurer,它替代了 Spring XML 文件中 Apache Camel 的 propertyPlaceholder 元素和 Spring 的 ctx:property-placeholder 元素。然后,您可以使用 Spring ${PropName} 语法或 Apache Camel {{ PropName}} 语法来引用配置的属性。

例如,定义从 cheese.properties 文件中读取其属性设置的桥接属性占位符:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:ctx="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

  <!-- Bridge Spring property placeholder with Camel -->
  <!-- Do not use <ctx:property-placeholder ... > at the same time -->
  <bean id="bridgePropertyPlaceholder"
        class="org.apache.camel.spring.spi.BridgePropertyPlaceholderConfigurer">
    <property name="location"
              value="classpath:org/apache/camel/component/properties/cheese.properties"/>
  </bean>

  <!-- A bean that uses Spring property placeholder -->
  <!-- The ${hi} is a spring property placeholder -->
  <bean id="hello" class="org.apache.camel.component.properties.HelloBean">
    <property name="greeting" value="${hi}"/>
  </bean>

  <camelContext xmlns="http://camel.apache.org/schema/spring">
    <!-- Use Camel's property placeholder {{ }} style -->
    <route>
      <from uri="direct:{{cool.bar}}"/>
      <bean ref="hello"/>
      <to uri="{{cool.end}}"/>
    </route>
  </camelContext>

</beans>
Copy to Clipboard Toggle word wrap
注意

另外,您可以设置 BridgePropertyPlaceholderConfigurerlocation 属性,使其指向 Spring 属性文件。完全支持 Spring 属性文件语法。

返回顶部
Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。 了解我们当前的更新.

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

Theme

© 2025 Red Hat