Spencer
Spencer

Reputation: 473

How to invoke a method on a servlet or controller after the web container has successfully started

I am implementing a RESTful web service with Spring MVC. When the service starts, it needs to register itself so that clients can find it. I'm currently doing this in the @PostConstruct method of the @Controller class. But this registers the service before it's actually ready to receive requests, because the web container isn't yet listening for web requests. I'd prefer to register the service after the web container has finished all of its initialization and is listening for requests.

I've looked for a listener and/or event that will notify me when the container is started, but I haven't found one.

I may be "prematurely optimizing". The eventual full deployment environment will need to load-balance a set of replicas of each service, and the load balancer will have to take care of determining actual service availability and current load for each instance.

Edit: additional clarification.

I want to register the service with an external registry (specifically, in this case, a Zookeeper instance.) I would prefer that the service not be added to the registry until the application server has finished initializing and is "open for business." When I use @PostConstruct, which appears to give the same basic sequencing as ServletContextListener.contextInitialized(), my log output looks something like this:

INFO : MyController - Registering service foo 0.1.0 at 192.168.34.15:8080
...
May 7, 2012 3:42:49 PM org.apache.coyote.http11.Http11Protocol init
INFO: Initializing Coyote HTTP/1.1 on http-8080
May 7, 2012 3:42:49 PM org.apache.coyote.http11.Http11Protocol start
INFO: Starting Coyote HTTP/1.1 on http-8080

What I'd like to see instead is this:

INFO: Starting Coyote HTTP/1.1 on http-8080
...
INFO : MyController - Registering service foo 0.1.0 at 192.168.34.15:8080
...

Upvotes: 2

Views: 613

Answers (2)

Bozho
Bozho

Reputation: 597026

The listener you are looking for is javax.servlet.ServletContextListener and its contextInitialized(..) method (and register it with either <listener><listener-class>.. in web.xml, or with @WebListener)

If you need a spring bean there, you can use:

WebApplicationContextUtils.getRequiredWebApplicationContext(ctx).getBean(..);

Upvotes: 3

Aaron Digulla
Aaron Digulla

Reputation: 328556

My first guess was that you should look at javax.servlet.ServletContextListener but I'm not sure if that will help you since Spring is usually initialized in exactly such a listener. Check your web.xml for a line like this:

<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

If that is there, then the ApplicationContext will be created right after the context has been created (in theory, the application can serve requests at this time but in practice, you're in the final configuration phase).

So the question is what you want to achieve. If you want to create a new bean for each request, use the "request" scope.

If you just want to delay the bean creation, then you should give a technical reason for doing so.

Upvotes: 0

Related Questions