我试图使用spring事件实现一个事件框架.我发现spring事件框架的默认行为是sync.但是在spring上下文初始化期间,如果它找到一个id为applicationEventMulticaster的bean,它会表现为异步.
现在我想在我的应用程序中同时拥有同步和异步事件发布者,因为某些事件需要同步发布.我尝试使用SysncTaskExecutor配置同步事件多播器,但我无法找到将其注入我的AsyncEventPublisher的applicationEventPublisher属性的方法.我的弹簧配置文件如下
<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor" destroy-method="shutdown">
<property name="corePoolSize" value="5" />
<property name="maxPoolSize" value="10" />
<property name="WaitForTasksToCompleteOnShutdown" value="true" />
</bean>
<bean id="syncTaskExecutor" class="org.springframework.core.task.SyncTaskExecutor" />
<bean id="customEventPublisher" class="x.spring.event.CustomEventPublisher" />
<bean id="customEventHandler" class="x.spring.event.CustomEventHandler" />
<bean id="eventSource" class="x.spring.event.EventSource" />
<bean id="responseHandler" class="x.spring.event.ResponseHandler" />
<bean id="syncEventSource" class="x.spring.event.syncEventSource" />
<bean id="applicationEventMulticaster" class="org.springframework.context.event.SimpleApplicationEventMulticaster">
<property name="taskExecutor" ref="taskExecutor" />
</bean>
<bean id="syncApplicationEventMulticaster" class="org.springframework.context.event.SimpleApplicationEventMulticaster">
<property name="taskExecutor" ref="syncTaskExecutor" />
</bean>
Run Code Online (Sandbox Code Playgroud)
有人可以帮我从这里出去吗 ?
小智 7
我只需要自己解决这个问题。默认情况下,事件是异步发送的,除非您实现了标记接口,在我的例子中,我将其称为 SynchronousEvent。您的配置中也需要一个“执行器”(我省略了我的,因为它是相当定制的)。
@EnableAsync
@SpringBootConfiguration
public class BigFishConfig {
@Autowired AsyncTaskExecutor executor;
@Bean
public ApplicationEventMulticaster applicationEventMulticaster() {
log.debug("creating multicaster");
return new SimpleApplicationEventMulticaster() {
@Override
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type = eventType != null ? eventType : ResolvableType.forInstance(event);
if (event instanceof PayloadApplicationEvent
&& ((PayloadApplicationEvent<?>) event).getPayload() instanceof SynchronousEvent)
getApplicationListeners(event, type).forEach(l -> invokeListener(l, event));
else
getApplicationListeners(event, type).forEach(l -> executor.execute(() -> invokeListener(l, event)));
}
};
}
...
Run Code Online (Sandbox Code Playgroud)
小智 5
不,你不能这样做,spring的initApplicationEventMulticaster只是init了一个,并且BeanName必须是applicationEventMulticaster。所以你只需选择以下执行器之一:
不管怎样,你可以修改 org.springframework.context.event.SimpleApplicationEventMulticaster 添加你的逻辑,然后你可以控制是否需要同步/异步
/**
* Initialize the ApplicationEventMulticaster.
* Uses SimpleApplicationEventMulticaster if none defined in the context.
* @see org.springframework.context.event.SimpleApplicationEventMulticaster
*/
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isDebugEnabled()) {
logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
else {
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
if (logger.isDebugEnabled()) {
logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
"': using default [" + this.applicationEventMulticaster + "]");
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4161 次 |
| 最近记录: |