Как настроить издатели Async и Sync Event, используя spring
Я пытаюсь реализовать фреймворк событий с помощью событий spring. Я узнал, что поведение по умолчанию в структуре событий spring является синхронизацией. Но при инициализации контекста spring, если он находит bean с id applicationEventMulticaster, он ведет Async.
Теперь я хочу, чтобы в моем приложении были как издатели событий sync, так и async, потому что некоторые события должны быть опубликованы в синхронизации. Я попытался настроить multicaster события синхронизации с помощью SysncTaskExecutor, но я не могу найти способ вставить его в свойство AsyncEventPublisher applicationEventPublisher.
Мой конфигурационный файл spring приведен ниже
<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>
Может ли кто-нибудь помочь мне здесь?
Ответы
Ответ 1
нет, вы не можете этого сделать, spring initApplicationEventMulticaster просто инициализирует только один, а BeanName должен быть applicationEventMulticaster. поэтому вы можете выбрать один из ниже Исполнитель:
- org.springframework.core.task.SyncTaskExecutor
- org.springframework.core.task.SimpleAsyncTaskExecutor
- ваш собственный Исполнитель: org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor
вы можете изменить org.springframework.context.event.SimpleApplicationEventMulticaster
для добавления вашей логики, тогда вы можете контролировать необходимость синхронизации /Async
/**
* 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 + "]");
}
}
}
Ответ 2
Я не умею редактировать с помощью stackoverflow. простите меня.
Мне не нужно добавлять комментарий, который вы можете хорошо знать. это синхронизировано. этот исполнитель запускает задачу последовательно и блокируется для каждой задачи.
public class SyncTaskExecutor implements TaskExecutor, Serializable {
/**
* Executes the given {@code task} synchronously, through direct
* invocation of it {@link Runnable#run() run()} method.
* @throws IllegalArgumentException if the given {@code task} is {@code null}
*/
@Override
public void execute(Runnable task) {
Assert.notNull(task, "Runnable must not be null");
task.run();
}
}
- SimpleAsyncTaskExecutor
Этот класс очень большой, поэтому я просто выбираю раздел кода. Если вы дадите threadFactory, будет извлечен поток из этого factory или будет создавать новый поток.
protected void doExecute(Runnable task) {
Thread thread = (this.threadFactory != null ? this.threadFactory.newThread(task) : createThread(task));
thread.start();
}
- ThreadPoolTaskExecutor
этот класс использует jdk5 current pkg ThreadPoolTaskExecutor. но spring инкапсулировать функциональность. spring хорош таким образом, jdk6 current и jdk7'current pkg имеют некоторую разницу.
это будет получить Thread от ThreadPool и повторно использовать его, выполнить каждую задачу Asynchronized. Если вы хотите узнать больше деталей, см. Исходный код JKD.
Ответ 3
Я попробовал ниже учебник:
https://www.keyup.eu/en/blog/101-synchronous-and-asynchronous-spring-events-in-one-application
Это помогает сделать синхронизацию и асинхронную многоадресную рассылку и создает над ними оболочку. Убедитесь, что имя класса-оболочки (DistributiveEventMulticaster) - applicationEventMulticaster.