camel-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Benjamin Legendre <jef...@free.fr>
Subject Re: How to instanciate a bean in camel registry for use with @produce annotation
Date Wed, 08 Jul 2015 09:14:30 GMT
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/

Mime
View raw message