camel-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Claus Ibsen <claus.ib...@gmail.com>
Subject Re: How to instanciate a bean in camel registry for use with @produce annotation
Date Wed, 08 Jul 2015 09:27:06 GMT
Hi

Ah well you cannot do like that as Camel is not a bean container like
spring etc. When you refer to the .class then Camel creates a new
instance once (because it has cache = true by default).

You need to create a bean instance and register it in the registry and
then you can use it as singleton. And you do not have to implement
that interface.


registry.put("myBean", new MyBean());


  .bean("myBean", "myMethod")
  .bean("myBean", "myMethod")
  .bean("myBean", "myMethod")

On Wed, Jul 8, 2015 at 11:14 AM, Benjamin Legendre <jeff58@free.fr> wrote:
> Sounds good unfortunately this doesn't work.
>
> Here is a simple case which reproduces the problem:
>
> -------------------------------------------------------------------------------
> Main class:
>
> package fr.cameltest;
>
> import org.apache.camel.CamelContext;
> import org.apache.camel.ProducerTemplate;
> import org.apache.camel.builder.RouteBuilder;
> import org.apache.camel.impl.DefaultCamelContext;
> import org.apache.camel.impl.SimpleRegistry;
>
> public class TestSingleton {
>
>     public static void main(String[] args) throws Exception {
>
>         SimpleRegistry registry = new SimpleRegistry();
>         CamelContext context = new DefaultCamelContext(registry);
>
>         context.addRoutes(new RouteBuilder(){
>
>             public void configure() {
>
>                 from("direct:fire")
>                     .bean(MyBean.class, "myMethod", false, true)
>                     .bean(MyBean.class, "myMethod", false, true)
>                     .bean(MyBean.class, "myMethod", false, true)
>                     .log("${body}");
>
>             }
>
>         });
>
>         context.start();
>         ProducerTemplate mainRouteLauncher = context.createProducerTemplate();
>         mainRouteLauncher.sendBody("direct:fire", "Hi!");
>         context.stop();
>
>     }
>
> }
>
> ---------------------------------------------------------------------------
> MyBean class:
>
> package fr.cameltest;
>
> import org.apache.camel.IsSingleton;
>
> public class MyBean implements IsSingleton {
>
>     public MyBean() {
>         System.out.println("MyBean has been instanciated");
>     }
>
>     public boolean isSingleton() {
>         return true;
>     }
>
>     public String myMethod(String body) {
>         return body;
>     }
> }
>
> ---------------------------------------------------------------------------
>
> Executing this case shows that the bean has been instanciated three times:
>
> [fr.cameltest.TestSingleton.main()] INFO org.apache.camel.impl.DefaultCamelContext -
Apache Camel 2.15.2 (CamelContext: camel-1) is starting
> [fr.cameltest.TestSingleton.main()] INFO org.apache.camel.management.ManagedManagementStrategy
- JMX is enabled
> [fr.cameltest.TestSingleton.main()] INFO org.apache.camel.impl.converter.DefaultTypeConverter
- Loaded 186 type converters
> MyBean has been instanciated
> MyBean has been instanciated
> MyBean has been instanciated
> [fr.cameltest.TestSingleton.main()] INFO org.apache.camel.impl.DefaultCamelContext -
AllowUseOriginalMessage is enabled. If access to the original message is not needed, then
its recommended to turn this option off as it may improve performance.
> [fr.cameltest.TestSingleton.main()] INFO org.apache.camel.impl.DefaultCamelContext -
StreamCaching is not in use. If using streams then its recommended to enable stream caching.
See more details at http://camel.apache.org/stream-caching.html
> [fr.cameltest.TestSingleton.main()] INFO org.apache.camel.impl.DefaultCamelContext -
Route: route1 started and consuming from: Endpoint[direct://fire]
> [fr.cameltest.TestSingleton.main()] INFO org.apache.camel.impl.DefaultCamelContext -
Total 1 routes, of which 1 is started.
> [fr.cameltest.TestSingleton.main()] INFO org.apache.camel.impl.DefaultCamelContext -
Apache Camel 2.15.2 (CamelContext: camel-1) started in 0.270 seconds
> [fr.cameltest.TestSingleton.main()] INFO route1 - Hi!
> [fr.cameltest.TestSingleton.main()] INFO org.apache.camel.impl.DefaultCamelContext -
Apache Camel 2.15.2 (CamelContext: camel-1) is shutting down
> [fr.cameltest.TestSingleton.main()] INFO org.apache.camel.impl.DefaultShutdownStrategy
- Starting to graceful shutdown 1 routes (timeout 300 seconds)
> [Camel (camel-1) thread #0 - ShutdownTask] INFO org.apache.camel.impl.DefaultShutdownStrategy
- Route: route1 shutdown complete, was consuming from: Endpoint[direct://fire]
> [fr.cameltest.TestSingleton.main()] INFO org.apache.camel.impl.DefaultShutdownStrategy
- Graceful shutdown of 1 routes completed in 0 seconds
> [fr.cameltest.TestSingleton.main()] INFO org.apache.camel.impl.DefaultCamelContext -
Apache Camel 2.15.2 (CamelContext: camel-1) uptime 0.293 seconds
> [fr.cameltest.TestSingleton.main()] INFO org.apache.camel.impl.DefaultCamelContext -
Apache Camel 2.15.2 (CamelContext: camel-1) is shutdown in 0.009 seconds
>
>
>
>
>
>
>
>
>
>
> ----- Mail original -----
> De: "Claus Ibsen" <claus.ibsen@gmail.com>
> À: users@camel.apache.org
> Envoyé: Mardi 7 Juillet 2015 15:44:28
> Objet: Re: How to instanciate a bean in camel registry for use with @produce annotation
>
> You can implement the IsSingleton interface on your bean
>
> On Mon, Jul 6, 2015 at 3:50 PM, Benjamin Legendre <jeff58@free.fr> wrote:
>>> If you refer to the bean just by the classname, then Camel creates an
>>> instance and does the IoC (eg also @Produce) etc.
>>
>> Is there a way to set a bean in the registry and telling Camel doing the IoC ?
>> Something like camelContext.addBean("name", class) ...
>>
>>> There is a boolean option afair to cache it, you can maybe do
>>>
>>>.bean(class, method, true)
>>
>> It should be definitively the answer. Morevover it avoids doing registry bindings
manually.
>>
>> Unfortunately I tried this before posting as it sounded but i can't figured how to
make it to work.
>> More precisely i tried .bean(class, method, false, true) because the third parameter
is "multiParameterArray" but
>> everytime i have a .bean(class, method, false, true) statement in my route it recreates
an instance.
>>
>> In the Javadoc, for the ProcessorDefinition::bean method, it is mentionned
>> "[...] Cache can be enabled if the bean in the Registry is defined as a singleton
scope."
>> I don't really understand. Is there something to do related to this ?
>>
>> So, as it is not a big issue i'll do the "manual way".
>>
>> Thanks
>>
>> ----- Mail original -----
>> De: "Claus Ibsen" <claus.ibsen@gmail.com>
>> À: users@camel.apache.org
>> Envoyé: Lundi 6 Juillet 2015 14:59:16
>> Objet: Re: How to instanciate a bean in camel registry for use with @produce annotation
>>
>> On Mon, Jul 6, 2015 at 2:23 PM, Benjamin Legendre <jeff58@free.fr> wrote:
>>> Thanks Hans and Claus for answer.
>>>
>>> Hans,
>>>
>>> I don't use Spring so i don't know what @Autowire is about.
>>>
>>> What i try to achieve is simply use a ProducerTemplate instance inside the "normalize"
method to
>>> retrieve data from a jdbc endpoint using producerTemplate.requestBodyAndHeader("jdbc:")
>>>
>>> I can get it to work by setting it manually:
>>>
>>>     SimpleRegistry registry = new SimpleRegistry();
>>>     CamelContext context = new DefaultCamelContext(registry);
>>>
>>>     DigitalTimeSeriesNormalizer dtsn = new DigitalTimeSeriesNormalizer();
>>>     dgtsn.producerTemplate = context.createProducerTemplate();
>>>     registry.put("dtsn", dtsn);
>>>
>>
>> Here you create the bean yourself with the new constructor. Camel just
>> use this instance as-is.
>>
>>> But i though it was cleaner using @Produce (and more handy in my case). Maybe
i miss the point here ?
>>>
>>>
>>
>> If you refer to the bean just by the classname, then Camel creates an
>> instance and does the IoC (eg also @Produce) etc.
>>
>> There is a boolean option afair to cache it, you can maybe do
>>
>> .bean(class, method, true)
>>
>>
>>
>>> Claus,
>>>
>>> Using .beanRef("beanName") is already what i do.
>>> But i noticed that using .bean(MyBean.class) makes the @Produce
>>> to works but has the drawback of creating many instances.
>>>
>>> I'm sorry if wasn't clear.
>>>
>>> Thanks
>>>
>>>
>>> ----- Mail original -----
>>> De: "Claus Ibsen" <claus.ibsen@gmail.com>
>>> À: users@camel.apache.org
>>> Envoyé: Lundi 6 Juillet 2015 13:26:43
>>> Objet: Re: How to instanciate a bean in camel registry for use with @produce
annotation
>>>
>>> Refer to it by its name, and use beanRef
>>>
>>> .beanRef("dtsm", "normalize")
>>>
>>> On Mon, Jul 6, 2015 at 12:36 PM, Benjamin Legendre <jeff58@free.fr> wrote:
>>>> Hi,
>>>> I'm using Camel 2.15.2 inside a stand alone java application.
>>>>
>>>> I do not figure how to add a bean in the Camel context in order to inject
a ProducerTemplate using @Produce on a property of my bean.
>>>> I my scenario The producer is not injected.
>>>>
>>>>
>>>> Here is the bean binding:
>>>>
>>>>         SimpleRegistry registry = new SimpleRegistry();
>>>>         registry.put("dtsm", new DigitalTimeSeriesNormalizer());
>>>>         CamelContext context = new DefaultCamelContext(registry);
>>>>
>>>>
>>>> The bean is then called like this is the route:
>>>>
>>>>         .beanRef("dtsm", "normalize")
>>>>
>>>>
>>>> Here is the code inside the bean:
>>>>
>>>> public class DigitalTimeSeriesNormalizer {
>>>>
>>>>     @Produce
>>>>     public ProducerTemplate producerTemplate;
>>>>
>>>>     [...]
>>>>
>>>>     public ArrayList<TimeSerie> normalize(ArrayList<TimeSerie>
timeSeries) {
>>>>
>>>>          this.producerTemplate // is null here
>>>>
>>>>     [...]
>>>> }
>>>>
>>>> It works when i use this syntax:
>>>>
>>>> .bean(DigitalTimeSeriesNormalizer.class, "normalize")
>>>>
>>>> But it is not what i want because a new instance of the bean is created each
time it is called on the route.
>>>> If this is the only way to make it to work, is there a way to make camel
instanciate it only one time and use a reference of the bean the next time ?
>>>>
>>>> Thanks in advance.
>>>> Benjamin
>>>
>>>
>>>
>>> --
>>> Claus Ibsen
>>> -----------------
>>> Red Hat, Inc.
>>> Email: cibsen@redhat.com
>>> Twitter: davsclaus
>>> Blog: http://davsclaus.com
>>> Author of Camel in Action: http://www.manning.com/ibsen
>>> hawtio: http://hawt.io/
>>> fabric8: http://fabric8.io/
>>
>>
>>
>> --
>> Claus Ibsen
>> -----------------
>> Red Hat, Inc.
>> Email: cibsen@redhat.com
>> Twitter: davsclaus
>> Blog: http://davsclaus.com
>> Author of Camel in Action: http://www.manning.com/ibsen
>> hawtio: http://hawt.io/
>> fabric8: http://fabric8.io/
>
>
>
> --
> Claus Ibsen
> -----------------
> Red Hat, Inc.
> Email: cibsen@redhat.com
> Twitter: davsclaus
> Blog: http://davsclaus.com
> Author of Camel in Action: http://www.manning.com/ibsen
> hawtio: http://hawt.io/
> fabric8: http://fabric8.io/



-- 
Claus Ibsen
-----------------
Red Hat, Inc.
Email: cibsen@redhat.com
Twitter: davsclaus
Blog: http://davsclaus.com
Author of Camel in Action: http://www.manning.com/ibsen
hawtio: http://hawt.io/
fabric8: http://fabric8.io/

Mime
View raw message