Passing a Spring bean to a Camel component

ぐ巨炮叔叔 提交于 2019-12-11 04:48:26

问题


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?

回答1:


If you have a singleton instance of Monitor you ought to be able to @Autowire it in the FooComponent class. As Camel will let Spring dependency inject when creating the FooComponent.

Then you can pass on the monitor instance when you create the endpoint / consumer from your component.




回答2:


The easiest thing to do is to create a Monitor property on the FooComponent class, and wire it in like any other bean.

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

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

Then in your FooConsumer, when you need to get hold of the monitor, call:

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

If you were changing the monitor bean on a per-endpoint basis, you could use Camel's nifty # syntax to locate a bean with that id, and inject it into an Endpoint property.

foo:something?monitor=#monitorBean

Then to use it in your FooConsumer you simply say:

Monitor monitor = ((FooEndpoint) getEndpoint()).getMonitor();


来源:https://stackoverflow.com/questions/18224264/passing-a-spring-bean-to-a-camel-component

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!