2013-02-15 104 views
1

我想使用Spring Event在我的Web应用程序中与我的bean“说话”。弹簧事件和范围请求

因此,举例来说,我的豆它将触发事件是这样的:

@Controller 
@Scope("request") 
@KeepAlive 
public class Controller extends InitializingBean, ApplicationEventPublisherAware { 

private ApplicationEventPublisher applicationEventPublisher;  

public void test() { 
    applicationEventPublisher.publishEvent(new TestEvent(this)); 
} 

} 

我的监听事件是这样的:

@Component 
@Scope("request") 
@KeepAlive 
public class Module implements ApplicationListener<TestEvent> { 

    @Override 
    public void onApplicationEvent(TestEvent event) { 

    } 

} 

最重要的一点是,这些豆类范围要求因为每次调用页面时都需要初始化它们。

但在启动时,我得到这个消息:

致:java.lang.IllegalStateException:没有线程绑定请求 发现:你是指请求属性的实际 Web请求外,或者在原来的 接收线程之外处理请求?如果您实际上在网络请求 中运行,但仍然收到此消息,则您的代码可能在DispatcherServlet/DispatcherPortlet的 之外运行:在这种情况下,请使用 RequestContextListener或RequestContextFilter来公开当前的 请求。

一样,如果春季尝试实例我模块豆在启动和作为bean是范围的要求,就不能做到这一点(上下文请求不被实例化)

如果我删除事件管理,一切工作正常。

所以,我的问题是:

是否有可能有事件监听器是范围的要求吗?以及如何做到这一点?

感谢

回答

0

尝试注入范围代理在辛格尔顿ApplicationListener处理TestEvent。

@Scope(proxyMode=ScopedProxyMode.TARGET_CLASS, value="request") 
public class TestEventHandler { 

    public void onTestEvent(TestEvent event) 
     // ... 
    } 

} 
    public class TestEventApplicationListener implements ApplicationListener<TestEvent> { 

    @Autowired 
    private TestEventHandler handler; 

    @Override 
    public void onApplicationEvent(TestEvent event) { 

     handler.onTestEvent(event); 

    } 
} 
+0

我不能这样做,因为Spring在每次调用“getModule”方法时都会给出一个新实例,并且每个请求都没有实例。这是请求代理的问题 – Kiva 2013-02-18 09:31:25

+0

由于您的事件处理程序不直接实现ApplicationListener并通过组合获取事件(自3.0开始已经过滤),您的初始问题已解决。由于您的事件处理程序现在是一个aop作用域代理,它可以注入一个singleton bean中。请参阅http://static.springsource.org/spring/docs/current/spring-framework-reference/html/beans.html#beans-factory-scopes-other-injection – 2013-02-18 11:06:32