Hi Claus, 

Ok, But when we register the bean manually in the registry, 
Camel does not bind a ProducerTemplate instance in the bean property 
annoted with @Produce (this is my initial issue).

It does when using .bean(MyBean.class, "MyMethod") because of IoC has you said.
Unfortunately, this syntax has the drawback of creating many instances if 
called 
many times in the route which is not desirable in my scenario.

Maybe i want the best of both worlds but it is simply not possible!



----- Mail original -----
De: "Claus Ibsen" <[email protected]>
À: [email protected]
Envoyé: Mercredi 8 Juillet 2015 11:27:06
Objet: Re: How to instanciate a bean in camel registry for use with @produce 
annotation

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 <[email protected]> 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" <[email protected]>
> À: [email protected]
> 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 <[email protected]> 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" <[email protected]>
>> À: [email protected]
>> 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 <[email protected]> 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" <[email protected]>
>>> À: [email protected]
>>> 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 <[email protected]> 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: [email protected]
>>> 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: [email protected]
>> 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: [email protected]
> 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: [email protected]
Twitter: davsclaus
Blog: http://davsclaus.com
Author of Camel in Action: http://www.manning.com/ibsen
hawtio: http://hawt.io/
fabric8: http://fabric8.io/

Reply via email to