Reputation: 343
I'm looking for an example/documentation of how to implement a custom Apache Camel component
and endpoint
with Spring Boot in Java Config. I don't know how I have to annotate the classes, that Could you please provide an example.
Without using Spring my (working) code looks like this:
public class MyCustomComponent extends DefaultComponent {
@Override
protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception {
Endpoint endpoint = new MyCustomEndpoint(uri, this);
setProperties(endpoint, parameters);
return endpoint;
}
}
Registered is the component in resources/META-INF/services/org/apache/camel/component/myscheme
with the FQN of the MyCustomComponent
class.
public class MyCustomEndpoint extends DefaultEndpoint {
public MyCustomEndpoint(String uri, MyCustomComponent component) {
super(uri, component);
}
@Override
public Producer createProducer() throws Exception {
return new MyCustomProducer(this);
}
@Override
public Consumer createConsumer(Processor processor) throws Exception {
throw new UnsupportedOperationException("Not implemented yet: MyCustomEndpoint#createConsumer");
}
@Override
public boolean isSingleton() {
return false;
}
}
public class MyCustomProducer extends DefaultProducer {
public MyCustomProducer(Endpoint endpoint) {
super(endpoint);
}
@Override
public void process(Exchange exchange) throws Exception {
}
}
Upvotes: 3
Views: 4684
Reputation: 343
After a lot of search I have found a solution on the base of Spring's BeanFactory
. The major obstacle are the circular dependencies (Component -> Endpoint -> Component | Endpoint -> Producer -> Endpoint). At first I have introduced a Spring Configuration
class:
@Configuration
public class ComponentConfiguration {
@Bean("myCustomEndpoint")
@Scope("prototype")
public MyCustomEndpoint myCustomEndpoint(String uri, MyCustomComponent component) {
MyCustomEndpoint endpoint = new MyCustomEndpoint(uri, component);
return endpoint;
}
@Bean("myCustomProducer")
@Scope("prototype")
public MyCustomProducer myCustomProducer(MyCustomEndpoint endpoint) {
return new MyCustomProducer(endpoint);
}
}
Make the custom Camel component a Spring component with @Component
annotation, so I'm able to inject the BeanFactory
to create an instance of the MyCustomEndpoint
class on demand (prototype
scope).
@org.springframework.stereotype.Component
public class MyCustomComponent extends DefaultComponent {
@Autowired
private BeanFactory beanFactory;
@Override
protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception {
MyCustomEndpoint endpoint = (MyCustomEndpoint) beanFactory.getBean("myCustomEndpoint", uri, this);
setProperties(endpoint, parameters);
return endpoint;
}
}
public class MyCustomEndpoint extends DefaultEndpoint {
@Autowired
private BeanFactory beanFactory;
public MyCustomEndpoint(String uri, MyCustomComponent component) {
super(uri, component);
}
@Override
public Producer createProducer() throws Exception {
MyCustomProducer producer = (MyCustomProducer) beanFactory.getBean("myCustomProducer", this);
return producer;
}
@Override
public Consumer createConsumer(Processor processor) throws Exception {
throw new UnsupportedOperationException("Not implemented yet: MyCustomEndpoint#createConsumer");
}
@Override
public boolean isSingleton() {
return true;
}
}
public class MyCustomProducer extends DefaultProducer {
// Now, I am able to inject some other Spring beans
@Autowired
private AnotherSpringBean bean;
public MyCustomProducer(Endpoint endpoint) {
super(endpoint);
}
@Override
public void process(Exchange exchange) throws Exception {
}
}
Note that the Camel component MyCustomComponent
is already registered in resources/META-INF/services/org/apache/camel/component/myscheme
:
class=<fqn-of-MyCustomComponent>
Upvotes: 5