2

我正在使用 Spring MVC 实现一个 RESTful Web 服务。当服务启动时,它需要注册自己,以便客户端可以找到它。我目前正在 @Controller 类的 @PostConstruct 方法中执行此操作。但这会在服务实际准备好接收请求之前注册服务,因为 Web 容器尚未侦听 Web 请求。我希望在 Web 容器完成所有初始化并正在侦听请求后注册服务。

我一直在寻找一个监听器和/或事件,它会在容器启动时通知我,但我还没有找到。

我可能“过早优化”。最终的完整部署环境将需要对每个服务的一组副本进行负载平衡,并且负载平衡器必须负责确定每个实例的实际服务可用性和当前负载。

编辑:附加说明。

我想向外部注册表注册服务(具体而言,在本例中是 Zookeeper 实例)。我希望在应用程序服务器完成初始化并“营业”之前不要将服务添加到注册表中。当我使用 @PostConstruct 时,它似乎给出了与 相同的基本顺序ServletContextListener.contextInitialized(),我的日志输出看起来像这样:

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

我想看到的是:

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

2 回答 2

3

您正在寻找的侦听器是javax.servlet.ServletContextListener及其方法(并在 web.xml 中或使用contextInitialized(..)注册它)<listener><listener-class>..@WebListener

如果你需要一个spring bean,你可以使用:

WebApplicationContextUtils.getRequiredWebApplicationContext(ctx).getBean(..);
于 2012-05-07T15:32:09.413 回答
0

我的第一个猜测是您应该查看javax.servlet.ServletContextListener但我不确定这是否会对您有所帮助,因为 Spring 通常是在这样的侦听器中初始化的。检查你web.xml的这样一行:

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

如果存在,那么ApplicationContext将在创建上下文后立即创建(理论上,应用程序此时可以服务请求,但实际上,您处于最终配置阶段)。

所以问题是你想要实现什么。如果要为每个请求创建一个新 bean,请使用“请求”范围。

如果您只是想延迟 bean 创建,那么您应该给出这样做的技术原因。

于 2012-05-07T15:39:38.833 回答