Как настроить издатели 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. простите меня.

  • SyncTaskExecutor

Мне не нужно добавлять комментарий, который вы можете хорошо знать. это синхронизировано. этот исполнитель запускает задачу последовательно и блокируется для каждой задачи.

 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();
}

}

  1. SimpleAsyncTaskExecutor

Этот класс очень большой, поэтому я просто выбираю раздел кода. Если вы дадите threadFactory, будет извлечен поток из этого factory или будет создавать новый поток.

    protected void doExecute(Runnable task) {
    Thread thread = (this.threadFactory != null ? this.threadFactory.newThread(task) : createThread(task));
    thread.start();
}
  1. 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.