问题
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 insideFooConsumer
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