【问题标题】:Populate java.util.Properties from camel property placeholder从骆驼属性占位符填充 java.util.Properties
【发布时间】:2015-04-21 09:50:41
【问题描述】:

我刚刚开始学习 OSGi 和 camel,我正在研究一些已经实现的服务。我有一个在 OSGi 蓝图的帮助下配置为在 Servicemix 上运行的包,有点像这样:

<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:camel-cxf="http://camel.apache.org/schema/blueprint/cxf"
xmlns:jaxrs="http://cxf.apache.org/jaxrs" xmlns:cxf="http://cxf.apache.org/blueprint/core"
xsi:schemaLocation="
    http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
    http://camel.apache.org/schema/cxf http://camel.apache.org/schema/cxf/camel-cxf.xsd
    http://cxf.apache.org/blueprint/core http://cxf.apache.org/schemas/blueprint/core.xsd
    http://camel.apache.org/schema/blueprint/cxf http://camel.apache.org/schema/blueprint/cxf/camel-cxf.xsd">

<camelContext id="ctx1"
    xmlns="http://camel.apache.org/schema/blueprint"
    xsi:schemaLocation="http://camel.apache.org/schema/blueprint http://camel.apache.org/schema/blueprint/camel-blueprint.xsd">
    <propertyPlaceholder location="properties/config.properties"/>
    <routeBuilder ref="..." />
</camelContext>

目前,config.properties 位于捆绑包内,但我正在尝试将其外部化。

所以,我将我的蓝图更改为:

<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:camel-cxf="http://camel.apache.org/schema/blueprint/cxf"
xmlns:jaxrs="http://cxf.apache.org/jaxrs" xmlns:cxf="http://cxf.apache.org/blueprint/core"
xsi:schemaLocation="
    http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
    http://camel.apache.org/schema/cxf http://camel.apache.org/schema/cxf/camel-cxf.xsd
    http://cxf.apache.org/blueprint/core http://cxf.apache.org/schemas/blueprint/core.xsd
    http://camel.apache.org/schema/blueprint/cxf http://camel.apache.org/schema/blueprint/cxf/camel-cxf.xsd">

<camelContext id="ctx1"
    xmlns="http://camel.apache.org/schema/blueprint"
    xsi:schemaLocation="http://camel.apache.org/schema/blueprint http://camel.apache.org/schema/blueprint/camel-blueprint.xsd">
    <propertyPlaceholder location="${karaf.home}/etc/config.properties"/>
    <routeBuilder ref="..." />
</camelContext>

... 这个配置工作得很好。

我面临的问题是,该属性文件还通过 java.util.properties 在多个位置使用,该文件作为一个简单文件加载到 util 文件的静态代码块中。

我可以在我的 Java 代码(骆驼代码除外)中使用骆驼上下文中加载的属性吗?

如果这是不可能的,那么我应该如何加载位于 servicemix 类路径中的属性文件,以便在骆驼上下文和 java 代码中使用,在我当前的实现中以最少的代码更改。 p>

【问题讨论】:

    标签: java apache-camel apache-karaf blueprint-osgi apache-servicemix


    【解决方案1】:

    我不鼓励在 OSGI 环境中使用对属性文件的静态访问。

    对我来说,最好的方法是创建一个 OSGI 服务,它公开验证方法或属性本身(使用 getter/setter),如下所示:

    <service ref="myConfig">
        <interfaces>
            <value>org.osgi.service.cm.ManagedService</value>
            <value>com.mycompany.services.common.api.MyConfig</value>
        </interfaces>
        <service-properties>
            <entry key="service.pid" value="config.properties" />
        </service-properties>
    </service>
    
    <bean id="myConfig" class="com.mycompany.services.common.config.MyConfigImpl" />
    

    在任何需要访问该属性的 OSGI 包之后,它可以通过以下方式引用:

    <reference id="myConfig" interface="com.mycompany.services.common.api.MyConfig"
        activation="eager" availability="mandatory" />
    

    在使用这种方式之前,由于使用了静态方法和 LOCK,我们在 bundle 之间遇到了很多死锁。 由于我们使用 OSGI 服务,因此在刷新/部署包时它可以正常工作。

    我假设您想通过任何其他 OSGI 包访问您的属性文件,而不是来自 OSGI 上下文的外部代码。 如果您想在 OSGI 上下文之外访问属性文件,我建议通过上述接口 (&lt;reference&gt;) 创建一个 (REST) Web 服务。

    实现示例:

    public class MyConfigImpl implements MyConfig, ManagedService {
    
        // This is just the property keys 
        private final static String COLORS = "my.valid.colors";
        private final static String PROP1 = "my.property.1";
        private final static String PROP2 = "my.property.2";
        private final static String PROP3 = "my.property.3";
    
        // For validating against some properties
        private List<String> colors = new ArrayList<>();
    
        // For extracting a subset of properties
        private String prop1;
        private String prop2;
        private String prop3;
    
        // The whole set of properties published as Dictionary (could be transformed in Map as well)
        private Dictionary props;
        
        @Override // Implements MyConfig.isValidColor(String color)
        public Boolean isValidColor(String color) {
            if (colors.contains(color)) {
                return true;
            } else {
                return false;
            }
        }
    
        @Override // Implements MyConfig.getPropertyOne()
        public String getPropertyOne(){
            return prop1;
        }
    
        @Override // Implements MyConfig.getPropertyTwo()
        public String getPropertyTwo(){
            return prop2;
        }
    
        @Override // Implements MyConfig.getPropertyThree()
        public String getPropertyThree(){
            return prop3;
        }
    
        @Override // Implements MyConfig.getProperties()
        public Dictionary getProperties(){
            return props;
        }
    
    
        // This implements the ManagedService.updated()
        @Override 
        public void updated(@SuppressWarnings("rawtypes") Dictionary properties) throws ConfigurationException {
            
            log.debug("Reading properties: {}", properties);
            if (properties == null) {
                return;
            }
    
            updateConfiguration(properties);
    
        }
    
        private void updateConfiguration(Dictionary properties) {
    
            // MyUtil.asListOfString is just a helper to convert comma separated string to list of String
            // This is just an example
            this.colors = MyUtil.asListOfStrings((String) properties.get(COLORS));
    
            this.prop1 = properties.get(PROP1);
            this.prop2 = properties.get(PROP2);
            this.prop3 = properties.get(PROP3);
            this.props = properties;
        }
    }
    

    【讨论】:

    • 我不认为我完全理解你的实现。这是什么 Myconfig 接口,我如何使用它来提取属性?你能详细说明一下,或者给我举一些例子吗??
    • 已更新示例。如果您需要很多属性,我认为最好的方法是导出 Dictionary 或将其转换为 Map。其他方法只是示例,不一定是最佳实践。
    • 实现派生自两个接口.. 你的来公开你想要的方法(在你的情况下,也许你只需要像 Map getProperties(); 和 ManagedService (OSGI) 来读取属性并更新 Bean .
    猜你喜欢
    • 2014-05-13
    • 2016-02-28
    • 1970-01-01
    • 2016-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-26
    相关资源
    最近更新 更多