apache-camel - 为什么 Camel SCR 被弃用?

标签 apache-camel apache-karaf

我正在研究 Camel-Scr,并在 pom.xml 中看到了

 <artifactId>camel-scr</artifactId>
 <name>Camel :: SCR (deprecated)</name>
 <description>Camel with OSGi SCR (Declarative Services)</description>

为什么这个被弃用了?社区将来会使用什么替代方案?

最佳答案

我的猜测是它对于所有的注释和属性来说太复杂了,因此与简单得多的 OSGi 蓝图相比可能没有太多用处。

OsgiDefaultCamelContext 的帮助下,使用带有声明式服务或 SCR 的 Apache Camel 非常简单。您可以手动创建上下文,添加路由和配置并使用 bundleContext.registerService 将其注册到 OSGi方法。

示例:

package com.example;

import java.util.Dictionary;
import java.util.Hashtable;
import java.util.Map;
import java.util.Properties;

import org.apache.camel.CamelContext;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.core.osgi.OsgiDefaultCamelContext;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component(
    immediate = true
)
public class OsgiDSCamelContextComponent {
    
    private final static Logger LOGGER = LoggerFactory.getLogger(ExampleCamelContext.class);

    CamelContext camelContext;
    ServiceRegistration<CamelContext> camelContextRegistration;

    @Activate
    public void onActivate(BundleContext bundleContext, Map<String, ?> configs){

        // Create new OsgiDefaultCamelContext with injected bundleContext
        OsgiDefaultCamelContext newCamelContext = new OsgiDefaultCamelContext(bundleContext);
        newCamelContext.setName("OsgiDSCamelContext");

        // Add configs from com.example.OsgiDSCamelContextComponent.cfg 
        // available for use with property placeholders 
        Properties properties = new Properties();
        properties.putAll(configs);
        newCamelContext.getPropertiesComponent()
            .setInitialProperties(properties);

        camelContext = newCamelContext;

        try {
            // In Apache Camel 3.x CamelContext needs to be started before adding RouteBuilders. 
            camelContext.start();
            camelContext.addRoutes(new RouteBuilder() {

                @Override
                public void configure() throws Exception {
                    
                    from("timer:exampleTimer?period=3000")
                        .routeId("exampleTimer")
                        .log("Hello from Camel using Declarative services");
                }
            });

            //Create dictionary holding properties for the CamelContext service.
            Dictionary serviceProperties = new Hashtable<>();
            serviceProperties.put("context.name", "OsgiDSCamelContext");
            serviceProperties.put("some.property", "SomeValue");

            // Register the new CamelContext instance as a service to Karaf with given properties
            camelContextRegistration = bundleContext.registerService(CamelContext.class, 
                camelContext, serviceProperties);
            
        } catch (Exception e) {
            LOGGER.error(e.getMessage(), e);
        }
    }

    @Deactivate
    public void onDeactivate(){

        // Stop camel context when bundle is stopped
        if(camelContext != null){
            camelContext.stop();
        }

        // unregister camel context service when bundle is stopped
        if(camelContextRegistration != null){
            camelContextRegistration.unregister();
        }
    }
}

现在您还可以使用 DS 服务组件来注册 RouteBuilder 服务并使用 @Reference 将它们注入(inject)到 CamelContext 中注释和 List<RouteBuilder> .

package com.example.routes;

import org.apache.camel.builder.RouteBuilder;
import org.osgi.service.component.annotations.Component;

@Component(
    immediate = true,
    property = {
        "target.context=exampleContext"
    },
    service = RouteBuilder.class
)
public class ExampleRouteBuilderService extends RouteBuilder {

    @Override
    public void configure() throws Exception {
     
        from("timer:exampleTimer?period=3000")
            .routeId("exampleTimer")
            .log("Hello from Camel using Declarative services");
    }
}
@Reference(
    target = "(target.context=exampleContext)",
    cardinality = ReferenceCardinality.AT_LEAST_ONE,
    policyOption = ReferencePolicyOption.GREEDY
)
List<RouteBuilder> routeBuilders;

在使用更高级的选项(如 @Modified)时要格外小心或 policy = ReferencePolicy.DYNAMIC因为这些可以防止在配置更改或列表被修改时重新创建上下文。这可能会导致路由被添加两次等问题。

OSGI R6 的依赖

<dependencies>
    <!-- OSGI -->
    <dependency>
        <groupId>org.osgi</groupId>
        <artifactId>osgi.core</artifactId>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.osgi</groupId>
        <artifactId>osgi.annotation</artifactId>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.osgi</groupId>
        <artifactId>osgi.cmpn</artifactId>
        <scope>provided</scope>
    </dependency>

    <!-- Camel -->
    <dependency>
        <groupId>org.apache.camel</groupId>
        <artifactId>camel-core</artifactId>
        <version>${camel.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.camel.karaf</groupId>
        <artifactId>camel-core-osgi</artifactId>
        <version>${camel.version}</version>
    </dependency>
</dependencies>

OSGI R8 的依赖

<dependencies>
    <dependency>
        <groupId>org.osgi</groupId>
        <artifactId>osgi.core</artifactId>
        <version>${osgi.version}</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.osgi</groupId>
        <artifactId>org.osgi.service.component.annotations</artifactId>
        <version>1.4.0</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.osgi</groupId>
        <artifactId>org.osgi.service.metatype.annotations</artifactId>
        <version>1.4.0</version>
        <scope>provided</scope>
    </dependency>

    <!-- Camel -->
    <dependency>
        <groupId>org.apache.camel</groupId>
        <artifactId>camel-core</artifactId>
        <version>${camel.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.camel.karaf</groupId>
        <artifactId>camel-core-osgi</artifactId>
        <version>${camel.version}</version>
    </dependency>
</dependencies>

关于apache-camel - 为什么 Camel SCR 被弃用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50670082/

相关文章:

java - ConversionPattern 用于在 JBossFuse/Apache Camel (ops4j) 中记录主机名

java - Camel : Write Message to WMQ

spring - 如何使 Camel 简单表达式与spring xml中的属性占位符一起使用

spring - Karaf 上的 Spring 应用程序示例

java - 大同记录 : specifying which timezone to use for logs

java - 将运行时参数传递给 OSGi felix scr 注释中的服务

java - Apache Camel如何从路由在FTP组件上应用readLock

java - 简单的camel ftp路由超时

java - 如何允许与 Karaf 远程连接(进行远程调试)?

java - karaf 中的 Spring Jdbc 声明式事务管理