Spring事件机制支持发布应用程序事件并通过@EventListener
批注在Spring组件中侦听这些事件。但是,在documentation中找不到关于在特定范围内发送事件的任何信息。我对Vaadin的具体需求是:
@UIScope
中的bean占用,即,不应影响其他用户UI 有可能吗?注意:这并不是Vaadin特有的。我还可以问一下Spring Web MVC请求范围如何实现。
答案 0 :(得分:1)
TL; DR:我认为它已经可以按照您的要求进行工作
长版:
文档尚不清楚,但是尝试了一个简单的测试:
发布事件的控制器:
@Controller
public class FooController {
@Autowired
private ApplicationEventPublisher publisher;
@GetMapping("/fireEvent")
public void fireEvent() {
publisher.publishEvent(new FooEvent(this));
}
}
还有一个侦听的作用域Bean:
@Scope(value = WebApplicationContext.SCOPE_REQUEST)
@Component
public class FooListener {
@EventListener(FooEvent.class)
public void listen() {
System.out.println("I'm listening. PS : I am "+this.toString());
}
}
并且在运行两个并发请求时,只有作用域相同的httprequest的侦听器才能获取事件。
我的解释(由于没有真正深入地研究过,因此请带一点盐):
在我看来,ApplicationEventMulticaster
的{{1}}使用BeanFactory来获取先前已注册为侦听器(按其名称)的bean。显然,工厂将在当前范围内返回一个bean。
答案 1 :(得分:0)
请查看这是否是您想要的:
主要应用程序:
package com.fg7.evision.EventList;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
@ComponentScan(basePackages = "com.fg7.evision.EventList")
public class EventApplication {
public static void main(String[] args) {
MyScopedEvent event = new MyScopedEvent("hello world");
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(EventApplication.class);
ctx.publishEvent(event);
}
}
事件:
package com.fg7.evision.EventList;
public class MyScopedEvent {
private String message;
public MyScopedEvent( String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}
事件侦听器仅作用于Singleton作用域。
package com.fg7.evision.EventList;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
@Component(value = "listener")
public class ScopedEventListener implements BeanNameAware {
@Autowired
ConfigurableApplicationContext context;
String beanName;
@Override
public void setBeanName(String name) {
this.beanName = name;
}
@EventListener(condition = "@listener.getScope() == 'singleton'")
public void handleEvent(MyScopedEvent myScopedEvent) {
System.out.println(myScopedEvent.getMessage());
}
public String getScope(){
return this.context.getBeanFactory().getBeanDefinition(this.beanName).getScope();
}
}