- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
一旦我的 spring web 应用程序启动了它的所有 bean,我就需要执行某个过程。为此,我创建了一个 ApplicationListener<ContextRefreshedEvent>
.
但是,当我运行该应用程序时,它会被调用多次(因为我们有不同命名空间的上下文,例如 mvc-servlet 等)但我需要这个特定的监听器只被调用一次,并且当所有上下文都正确初始化时.
有没有办法实现我想要做的事情?
我正在使用 spring 3.1.0.RELEASE。
最佳答案
是的,有办法,但可能有点棘手。您正在谈论的子上下文可能是为 DispatcherServlet
启动的上下文。如果您有不止一个,您将获得每个调度程序 servlet 的一个上下文。
Spring 将这些委托(delegate)给容器,因此在初始化方面没有单点管理。首先,初始化根应用程序上下文,然后由容器初始化各种 servlet。对于其中的每一个,另一个上下文可能会启动。
幸运的是,servlet 规范通过 load-on-startup
参数来拯救
The load-on-startup element indicates that this servlet should be loaded (instantiated and have its init() called) on the startup of the web application. The optional contents of these element must be an integer indicating the order in which the servlet should be loaded. If the value is a negative integer, or the element is not present, the container is free to load the servlet whenever it chooses. If the value is a positive integer or 0, the container must load and initialize the servlet as the application is deployed. The container must guarantee that servlets marked with lower integers are loaded before servlets marked with higher integers. The container may choose the order of loading of servlets with the same load-on-start-up value.
所以你基本上应该做两件事:
load-on-startup
元素,并确保每个 servlet 都有一个独特的、更大的数字考虑以下(简化的)web.xml
定义
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>anotherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/first/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>anotherServlet</servlet-name>
<url-pattern>/second/*</url-pattern>
</servlet-mapping>
</web-app>
此设置将导致对监听器的 3 次调用。在这种情况下,anotherServlet
是链中的最后一个,因此您可以按如下方式识别它:
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
ApplicationContext context = event.getApplicationContext();
if (context instanceof ConfigurableWebApplicationContext) { // sanity check
final ConfigurableWebApplicationContext ctx =
(ConfigurableWebApplicationContext) event.getApplicationContext();
if ("anotherServlet-servlet".equals(ctx.getNamespace())) {
// Run your initialization business here
}
}
}
如果您有兴趣了解它的来源,请查看 FrameworkServlet#initServletBean
。
并不是说此时您仍然可以抛出异常,这仍然会阻止应用程序正确部署。
最后,您还可以确保最后处理您的事件,以防为该特定事件注册了多个监听器。为此,您需要实现 Ordered
接口(interface):
public class YourListener implements ApplicationListener<ContextRefreshedEvent>, Ordered {
@Override
public void onApplicationEvent(ContextRefreshedEvent event) { }
@Override
public int getOrder() {
return Ordered.LOWEST_PRECEDENCE;
}
}
关于java - ContextRefreshEvent 的 Spring ApplicationListener。如何每个层次结构只调用一次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22229077/
我创建了一个spring-boot-troubleshooting repo on GitHub准确地重现了这个错误。 我正在构建基于 Spring Boot 的 REST 服务,但很难获得 star
我需要审核超时 logOut 事件,我搜索了一下并找到了解决方案。但这不起作用。当用户注销或超时时,根本不会调用事件方法。 这是我的代码:ObjectLock.java: @Component pub
ApplicationListener 和 ServletContextListener 有什么区别?你什么时候使用它们? implements ApplicationListener impleme
嘿,现在我正在制作一款 2D 游戏,适用于桌面和 Android。我安装了 libGDX,因为我听说它使用 java 开发游戏变得更容易。但是当我运行桌面代码时,它显示此错误 java: cannot
我有以下 ApplicationListener: package org.mycompany.listeners; import org.springframework.context.Applic
我想将对象传递到我的 ApplicationListener 实现中,但我不断收到 NullPointerExceptions,所以我可能做错了什么。 我收到异常:callback.onReady()
当我有多个实现 ApplicationListener 的 bean 时接口(interface),如何控制某些 bean 在其他 bean 之前被调用? 在 bean 本身内部处理依赖关系是否更有意
我使用 Spring Boot 编写了一个应用程序。我添加了一个监听 DataSourceInitializedEvent 的 ApplicationListener,但在应用程序启动期间尚未调用我的
我想在运行时而不是在 Spring 配置文件中动态注册和取消注册 Spring ApplicationListeners。 如果我不能动态删除它们,就会发生内存泄漏。 这是我最好的猜测: 我可以调用
我有几个服务正在监听 Spring 事件以更改我的底层数据模型。这些都是通过实现 ApplicationListener 来实现的。 .一旦所有Foo监听器修改底层数据模型,我的用户界面需要刷新以反射
我正在我的项目中导入一个 Spring Boot Starter,因为它包含一个我想使用但我不想运行自动配置的类。我可以在启动器中看到有一个 META-INF/spring.factories 文件,
我想在成功的用户身份验证后将对象添加到 HttpSession。 请不要使用 SavedRequestAwareAuthenticationSuccessHandler 建议解决方案,因为在此应用中对
我使用 Stomp over SockJS 和 Spring 消息传递。当新用户连接时,我试图向所有登录的用户发送消息。首先,这是我的听众: @Component public class Sessi
我们正在使用 libgdx 开发一款游戏,我们希望能够切换屏幕。我做了一个GameOverScreen,它实现了Screen: public class GameOverScreen implemen
是否可以从 ApplicationListener 关闭上下文? public class MyListener implements ApplicationListener { @Ov
嗨,我正在寻找一种方法来显示 Libgdx sprite 批处理或类似的东西,而不使用任何应用程序监听器、适配器或 Game 类。应该可以调用某个游戏对象的构造函数,然后调用它的纹理应该显示到批处理或
今天,当我打开 eclipse 时,这个错误突然出现在我的一个 libgdx 项目中 代码: public static void main (String[] argv) { if (app
我正在使用 Spring Security 3.2.5.RELEASE 并且很难捕获失败的登录尝试。我目前有一个 ApplicationListener 配置如下: @Component public
您可以使用如下代码根据您的网络服务关闭(或刷新/启动)的时间执行一些事件。 public class APIService implements ApplicationListener { @
一旦我的 spring web 应用程序启动了它的所有 bean,我就需要执行某个过程。为此,我创建了一个 ApplicationListener . 但是,当我运行该应用程序时,它会被调用多次(因为
我是一名优秀的程序员,十分优秀!