1

I have a custom component of type FooComponent which is added to the route by the following lines:

from("foo://bar?args=values&etc")
        .bean(DownstreamComponent.class)
        ...

FooComponent creates an endpoint and consumer (of type FooConsumer) which in turn emits messages which get to the DownstreamComponent and the rest of the pipeline.

For monitoring, I need the FooComponent consumer to call a method on a non-Camel object, which I'm creating as a Spring bean. The Camel pipeline is very performance sensitive so I'm unable to divide the FooComponent into two halves and insert the monitor call as a Camel component between them (my preferred solution, since FooComponent shouldn't really have to know about the monitor). And I'm reluctant to turn the method call into a Camel Message that will be picked up by the monitoring component later in the pipeline, as the pipeline filtering becomes complicated later and I don't want to meddle with it more than necessary.

Somewhere inside FooConsumer, I have:

// in the class
@Autowired
Monitor monitor;

// inside the consumer's run method
monitor.noticeSomething();

The problem is that monitor will never be set to the Monitor bean which is created in the rest of the application. As I understand it, it's because FooConsumer itself is not visible to Spring -- an object of that type is created normally inside FooComponent.

So, how can I get FooComponent to find the Monitor instance that it needs to use?

  • Can I pass it in when the route is created? This seems tricky because the definition is a faux URL "foo://bar?args=values&etc"; I haven't found how to pass Java objects that way.
  • Can I get Spring to find that @Autowired annotation inside FooConsumer and inject the monitor object somehow?
4

2 回答 2

4

如果你有一个 Monitor 的单例实例,你应该能够在 FooComponent 类中 @Autowire 它。因为 Camel 在创建 FooComponent 时会让 Spring 依赖注入。

然后,当您从组件创建端点/使用者时,您可以传递监视器实例。

于 2013-08-14T13:07:46.050 回答
4

最简单的做法是在类上创建一个Monitor属性FooComponent,然后像任何其他 bean 一样将其连接起来。

<bean id="monitorBean" class="my.Monitor"/>

<bean id="foo" class="my.FooComponent">
    <property name="monitor" ref="monitorBean"/>
</bean>

然后在你的FooConsumer,当你需要控制监视器时,调用:

Monitor monitor = ((FooComponent) getEndpoint().getComponent()).getMonitor();

如果您要基于每个端点更改监视器 bean,您可以使用 Camel 的漂亮#语法来定位具有该 id 的 bean,并将其注入到端点属性中。

foo:something?monitor=#monitorBean

然后在你的中使用它,FooConsumer你只需说:

Monitor monitor = ((FooEndpoint) getEndpoint()).getMonitor();
于 2013-08-14T11:01:28.037 回答