如何使用不同的 属性 占位符多次部署 camel/blueprint 服务
How to deploy a camel/blueprint service multiple times using different property placeholders
通常我们只部署一次基于 camel/blueprint 的服务。每个服务都有自己的 属性 占位符,并且 camel-context 绑定到它:
<cm:property-placeholder id="service-name.placeholder" persistent-id="service-name.blueprint">
<cm:default-properties>
...
</cm:default-properties>
</cm:property-placeholder>
...
<camelContext id="service-name-service-camel" xmlns="http://camel.apache.org/schema/blueprint"
useMDCLogging="true">
<propertyPlaceholder id="properties" location="blueprint:service-name.placeholder" />
<routeBuilder ref="mainRoute"/>
</camelContext>
现在我们创建了一个我们想要多次部署的服务。每个实例都应使用自己的一组 属性 值。
我看到的唯一方法是在编译时设置 属性 占位符名称(maven 过滤器),但这会导致不同的工件 - 不好。
有没有办法将 属性 占位符设置为在运行时或开始时使用?
您可以使用 ManagedServiceFactory 和几行代码来完成。
为工厂定义一个 bean,并注入 BundleContext。选择一个 Pid 以稍后识别和配置此工厂:
<bean id="myServiceFactory" class="org.my.MyServiceFactory" init-method="init" destroy-method="destroy">
<property name="bundleContext" ref="blueprintBundleContext"/>
<property name="configurationPid" value="org.my.pid"/>
</bean>
实施服务工厂(不是工作代码,只是给你一个想法):
public class MyServiceFactory implements ManagedServiceFactory {
private BundleContext bundleContext;
private String configurationPid;
public void setConfigurationPid(String configurationPid) {
this.configurationPid = configurationPid;
}
public void setBundleContext(BundleContext bundleContext) {
this.bundleContext = bundleContext;
}
public void init() {
// your setup goes here
}
public void destroy() {
// your shutdown logic goes here
}
@Override
public String getName() {
return configurationPid;
}
@Override
public void updated(String pid, Dictionary dict) throws ConfigurationException {
// Instantiate each service with its own properties
MyServiceImpl service = new MyServiceImpl(dict);
Dictionary servProps = new Properties();
servProps.put("custom.service.property", "an id or someting")
bundleContext.registerService(MyServiceImpl.class.getName(), service, servProps);
// save your servicereferences to unregister, eg in a map
// you can customize your service by giving some property to later retrieve it
}
@Override
public void deleted(String pid) {
// get the ServiceReference from some map
servicereference.unregister();
}
}
ManagedServiceFactory 有一个方法 init()
来设置所有必需的资源,一个 destroy()
方法来清理(例如通过注销所有服务)。
为 etc/org.my.pid-*.cfg
中的每个配置文件创建一个新的服务实例,例如创建一个服务的 3 个实例:
etc/org.my.pid-serviceinstance1.cfg
etc/org.my.pid-serviceinstance2.cfg
etc/org.my.pid-whatever.cfg
要获取服务的特定实例,请使用一些自定义 属性 注册它们(例如我的示例中的 custom.service.property
)。然后在消费者包中请求 MyService
的实例,其中 custom.service.property
= serviceinstance2 就完成了。
您甚至可以通过这种方式创建新的 CamelContext。 PacktPub 网站上有完整的教程。
编辑:
当您在 etc/org.my.pid-*
中写入新文件时,会调用 updated()
方法并部署新服务。删除文件时,将调用 deleted()
方法,您必须销毁并取消注册该服务。当然,您可以 add/delete/modify 文件 JBoss/Karaf 运行 :-) 而无需停止主包。
通常我们只部署一次基于 camel/blueprint 的服务。每个服务都有自己的 属性 占位符,并且 camel-context 绑定到它:
<cm:property-placeholder id="service-name.placeholder" persistent-id="service-name.blueprint">
<cm:default-properties>
...
</cm:default-properties>
</cm:property-placeholder>
...
<camelContext id="service-name-service-camel" xmlns="http://camel.apache.org/schema/blueprint"
useMDCLogging="true">
<propertyPlaceholder id="properties" location="blueprint:service-name.placeholder" />
<routeBuilder ref="mainRoute"/>
</camelContext>
现在我们创建了一个我们想要多次部署的服务。每个实例都应使用自己的一组 属性 值。 我看到的唯一方法是在编译时设置 属性 占位符名称(maven 过滤器),但这会导致不同的工件 - 不好。
有没有办法将 属性 占位符设置为在运行时或开始时使用?
您可以使用 ManagedServiceFactory 和几行代码来完成。
为工厂定义一个 bean,并注入 BundleContext。选择一个 Pid 以稍后识别和配置此工厂:
<bean id="myServiceFactory" class="org.my.MyServiceFactory" init-method="init" destroy-method="destroy">
<property name="bundleContext" ref="blueprintBundleContext"/>
<property name="configurationPid" value="org.my.pid"/>
</bean>
实施服务工厂(不是工作代码,只是给你一个想法):
public class MyServiceFactory implements ManagedServiceFactory {
private BundleContext bundleContext;
private String configurationPid;
public void setConfigurationPid(String configurationPid) {
this.configurationPid = configurationPid;
}
public void setBundleContext(BundleContext bundleContext) {
this.bundleContext = bundleContext;
}
public void init() {
// your setup goes here
}
public void destroy() {
// your shutdown logic goes here
}
@Override
public String getName() {
return configurationPid;
}
@Override
public void updated(String pid, Dictionary dict) throws ConfigurationException {
// Instantiate each service with its own properties
MyServiceImpl service = new MyServiceImpl(dict);
Dictionary servProps = new Properties();
servProps.put("custom.service.property", "an id or someting")
bundleContext.registerService(MyServiceImpl.class.getName(), service, servProps);
// save your servicereferences to unregister, eg in a map
// you can customize your service by giving some property to later retrieve it
}
@Override
public void deleted(String pid) {
// get the ServiceReference from some map
servicereference.unregister();
}
}
ManagedServiceFactory 有一个方法 init()
来设置所有必需的资源,一个 destroy()
方法来清理(例如通过注销所有服务)。
为 etc/org.my.pid-*.cfg
中的每个配置文件创建一个新的服务实例,例如创建一个服务的 3 个实例:
etc/org.my.pid-serviceinstance1.cfg
etc/org.my.pid-serviceinstance2.cfg
etc/org.my.pid-whatever.cfg
要获取服务的特定实例,请使用一些自定义 属性 注册它们(例如我的示例中的 custom.service.property
)。然后在消费者包中请求 MyService
的实例,其中 custom.service.property
= serviceinstance2 就完成了。
您甚至可以通过这种方式创建新的 CamelContext。 PacktPub 网站上有完整的教程。
编辑:
当您在 etc/org.my.pid-*
中写入新文件时,会调用 updated()
方法并部署新服务。删除文件时,将调用 deleted()
方法,您必须销毁并取消注册该服务。当然,您可以 add/delete/modify 文件 JBoss/Karaf 运行 :-) 而无需停止主包。