Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.spi;

import org.apache.camel.CamelContext;

/**
* A plugin interface that allows third-party components to perform initialization tasks when a CamelContext is being
* configured and started.
* <p>
* Implementations of this interface are automatically discovered and loaded via the Java ServiceLoader mechanism. To
* register a plugin, create a service provider configuration file at
* {@code META-INF/services/org.apache.camel.spi.ContextServicePlugin} containing the fully qualified class name of your
* implementation.
* <p>
* Common use cases include:
* <ul>
* <li>Registering beans in the Camel registry</li>
* <li>Adding event notifiers for monitoring</li>
* <li>Configuring global interceptors</li>
* <li>Setting up custom type converters</li>
* </ul>
*
* <h3>Example Usage:</h3>
*
* <pre>
* <code>
* public class MyContextServicePlugin implements ContextServicePlugin {
* &#64;Override
* public void load(CamelContext camelContext) {
* // Register a bean in the registry
* camelContext.getRegistry().bind("myBean", new MyBean());
*
* // Add an event notifier
* camelContext.getManagementStrategy().addEventNotifier(new MyEventNotifier());
* }
* }
* </code>
* </pre>
*
* @see org.apache.camel.impl.engine.DefaultContextServiceLoaderPlugin
*/
public interface ContextServicePlugin {

/**
* Called during CamelContext initialization to allow the plugin to configure or customize the context.
* <p>
* This method is invoked after the CamelContext has been created but before routes are started. Implementations
* should perform any necessary setup operations such as registering beans, adding event notifiers, or configuring
* global settings.
*
* @param camelContext the CamelContext being initialized, never {@code null}
*/
void load(CamelContext camelContext);
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
import org.apache.camel.StartupListener;
import org.apache.camel.StartupStep;
import org.apache.camel.StartupSummaryLevel;
import org.apache.camel.StatefulService;
import org.apache.camel.Suspendable;
import org.apache.camel.SuspendableService;
import org.apache.camel.TypeConverter;
Expand Down Expand Up @@ -349,6 +350,7 @@ protected AbstractCamelContext(boolean build) {
* Called during object construction to initialize context plugins
*/
protected void initPlugins() {
camelContextExtension.addContextPlugin(StatefulService.class, createContextServiceLoaderPlugin());
camelContextExtension.addContextPlugin(StartupConditionStrategy.class, createStartupConditionStrategy());
camelContextExtension.addContextPlugin(CamelBeanPostProcessor.class, createBeanPostProcessor());
camelContextExtension.addContextPlugin(CamelDependencyInjectionAnnotationFactory.class,
Expand Down Expand Up @@ -4471,6 +4473,8 @@ protected abstract EndpointRegistry createEndpointRegistry(

protected abstract StartupConditionStrategy createStartupConditionStrategy();

protected abstract StatefulService createContextServiceLoaderPlugin();

protected abstract BackOffTimerFactory createBackOffTimerFactory();

protected abstract TaskManagerRegistry createTaskManagerRegistry();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.impl.engine;

import java.util.ServiceLoader;

import org.apache.camel.CamelContext;
import org.apache.camel.CamelContextAware;
import org.apache.camel.spi.ContextServicePlugin;
import org.apache.camel.support.service.ServiceSupport;

/**
* Default implementation that automatically discovers and loads {@link ContextServicePlugin} implementations using the
* Java ServiceLoader mechanism.
* <p>
* This service is responsible for scanning the classpath for implementations of {@code ContextServicePlugin} and
* invoking their {@code load} method during CamelContext startup. Plugin implementations are discovered through service
* provider configuration files located at: {@code META-INF/services/org.apache.camel.spi.ContextServicePlugin}
* <p>
* The loading process occurs during the {@link #doStart()} phase, ensuring that all plugins are initialized before
* routes are started but after the CamelContext has been created and configured.
* <p>
* This class extends {@link ServiceSupport} to participate in the Camel service lifecycle and implements
* {@link CamelContextAware} to receive the CamelContext instance that plugins will operate on.
*
* @see ContextServicePlugin
* @see ServiceLoader
*/
public class DefaultContextServiceLoaderPlugin extends ServiceSupport implements CamelContextAware {
private CamelContext camelContext;

/**
* Discovers and loads all {@link ContextServicePlugin} implementations found on the classpath.
* <p>
* This method is called during service startup and uses {@link ServiceLoader} to automatically discover plugin
* implementations. Each discovered plugin's {@code load} method is invoked with the current CamelContext, allowing
* plugins to perform their initialization logic.
* <p>
* The plugins are loaded in the order they are discovered by the ServiceLoader, which may vary between JVM
* implementations and is generally not guaranteed to be deterministic.
*
* @throws Exception if any plugin fails to load or throws an exception during initialization
*/
@Override
protected void doStart() throws Exception {
ServiceLoader<ContextServicePlugin> contextServicePlugins = ServiceLoader.load(ContextServicePlugin.class);
for (ContextServicePlugin plugin : contextServicePlugins) {
plugin.load(camelContext);
}
}

@Override
public void setCamelContext(CamelContext camelContext) {
this.camelContext = camelContext;
}

@Override
public CamelContext getCamelContext() {
return camelContext;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.apache.camel.Processor;
import org.apache.camel.Route;
import org.apache.camel.RouteTemplateContext;
import org.apache.camel.StatefulService;
import org.apache.camel.TypeConverter;
import org.apache.camel.catalog.RuntimeCamelCatalog;
import org.apache.camel.console.DevConsoleRegistry;
Expand Down Expand Up @@ -755,6 +756,11 @@ protected StartupConditionStrategy createStartupConditionStrategy() {
return new DefaultStartupConditionStrategy();
}

@Override
protected StatefulService createContextServiceLoaderPlugin() {
return new DefaultContextServiceLoaderPlugin();
}

@Override
protected BackOffTimerFactory createBackOffTimerFactory() {
return new DefaultBackOffTimerFactory(this);
Expand Down