How to delay the launch of spring beans?

Having a spring application (actually a grails application) that starts the apache-activemq server as a spring bean and a couple of apache-camel routes. Using the hibernate application to work with the database. The problem is simple. Activemq + Camel launches BEFORE grails embeds special methods in hibernate domain objects (actually save / update methods, etc.). So, if activemq already has some startup data, the camel starts processing messages without using DAO grails. This is not performed using grails.lang.MissingMethodException . You must delay the start of activemq / camel before Grails injects custom methods into domain objects.

+7
spring grails
source share
4 answers

Can you move the MQ control to a plugin? This would increase modularity, and if you declare in a descriptor plugin

 def loadAfter = ['hibernate'] 

You must have the desired behavior. Works for JBPM Plugin

+4
source share

If all of them are defined as spring bean, you can use

 <bean id="activeMqBean" depends-on="anotherBean" /> 

This will cause anotherBean be initialized to activeMqBean

+4
source share

I'm not sure about your case, but lazy loading can also help, for example,

 <bean id="lazybean" class="com.xxx.YourBean" lazy-init="true"> 

The less-initialized bean tells the IoC container to instantiate the bean on the first request. This may help you to delay loading the beans you want.

+3
source share

I know this question is quite old, but now I am facing the same problem in 2015, and this thread does not offer me a solution.

I came up with a special bean processor with CountDownLatch, which I calculate after loading the application. Thus, the messages will be idle until the application starts working fully and works for me.

 /** * bootstrap latch processor */ @Log4j class BootstrapLatchProcessor implements Processor { private final CountDownLatch latch = new CountDownLatch(1) @Override void process(Exchange exchange) throws Exception { if(latch.count > 0){ log.info "waiting for bootstrapped @ ${exchange.fromEndpoint}" latch.await() } exchange.out = exchange.in } /** * mark the application as bootstrapped */ public void setBootstrapped(){ latch.countDown() } } 

Then use it as a bean in your application and call the setBootstrapped method in your Bootstrap.groovy

Then, in your RouteBuilder, you place the processor between your endpoint and the destination for all routes that you expect messages to be before the application starts:

 from("activemq:a.in ").processRef('bootstrapProcessor').to("bean:handlerService?method=handle") 
0
source share

All Articles