tags:

views:

2366

answers:

2

Suppose I have a couple of spring beans:

<beans>
   <bean name="A" ... />
   <bean name="B" ... />
</beans>

"B" exposes a remote service that doesn't need "A". Assume that "A" takes a non-negligble time to load. What this means is that during a restart cycle, the application hangs the remote client, which can actually connect to the server but waits for a response until the spring container fully initializes.

What I'd like to be able to do is have the "B" remote service respond immediately, even if (based on the application state) it can only return NOT_READY or some such. The container, however, forces a wait until all of it's beans are initialized, even if you specify the beans as lazy-init and irrespective of load order.

I suspect that having "B" available immediately would mean that spring would have to make available a partially initialized container, which sounds bad. However, I'd appreciate any information anyone's got on the initialization order and whether you've found any reasonable workarounds.

A: 

I do not understand, why "A takes a non-negligble time to load", but maybe you could to a lazy initialize yourself by refactoring A. Do not use InitializingBean or handle an ApplicationEvent. Just initialize on the first Request to be handled. This will slow down the first request!

The other possibility is to move the initialization to a separated thread created by the bean handling an ApplicationEvent. The thread calls the initialization method of the bean an async way. Be carefull to handle Requests to the uninitialized bean!

Arne Burmeister
While A loads, callers hang until timeout, as they can open a socket but wait for server initialization to complete.Want to manually load service to respond immediately. I was hoping to avoid the messy alternative of initializing in a manually started background thread.
Steve B.
+1  A: 

Don't refer to bean "A" directly. Instead, refer to a bean which is a FACTORY for bean "A"; in this way, the Factory bean can be created without taking the initialization hit for instantiating "A". You'll need to refactor your classes which refer to an "A" to retrieve an "A" first, of course.

Or, you could create a bean "AA", which is a container for bean "A", which has an initialization state, and which exposes the interface of bean "A"; upon invocation, it sets its initialization state to not initialized, and begins initialization of bean "A" in some thread; calls to any interface methods of "A" on "AA" can then either block or return a not ready response, until the initialization of "A" within "AA" has completed.

This all kinda hinges on what your definition of "takes a non-negligible time to load" is. Why does it take a non-negligible amount of time to load? Is there some particularly tricky initialization that's going on within A? Or is A just so monstrously huge that it chokes the JVM?

McWafflestix