Springにおける観察者モードの適用


Springにおける観察者モードの適用
SpringのApple Listenは観察者に相当します.Application Event Publisherは観察対象と見なすことができます.複数の観察者に通知する操作を実現するためには、Spring内のAppplication EventPublisheを使用することができます.観察者の動作は同期可能であり、非同期的でもある.
@Service
public class MyService {
    /**
     * Spring4.2  ,ApplicationEventPublisher          ,        Aware  。
     */
    @Autowired
    private ApplicationEventPublisher publisher;

    public void doSomething(){
        System.out.println(Thread.currentThread().getName()+ ":send the msg");
        //    
        publisher.publishEvent(new MyEvent("content"));
    }
}
/**
 *      
 */
public class MyEvent extends ApplicationEvent {
    public MyEvent(Object source) {
        super(source);
    }
}
/**
 *       (   )
 */
@Component
public class MyListener   {
    @EventListener
    public void reciveMsg(MyEvent myEvent){
        String msg = (String) myEvent.getSource();
        System.out.println(Thread.currentThread().getName()+ ": recive msg --"+msg);
    }
}
運転結果:service publisherを呼び出すpublishEven方法は、Appliation EventオブジェクトをMulticastオブジェクトに転送します.Multicastオブジェクトは、Application Eventに従って対応するモニターセットを取得し、このセットを繰り返して、各モニターの操作を実行します.このプロセスは同期しています.つまりserviceは観察者の操作が終わってから運行を続けなければなりません.観察者の非同期実行が必要な場合は、以下のように修正することができます.容器にカスタムExectorを追加し、起動クラスに@EnbaleAsync注解を追加します.
@Configuration
@ComponentScan
@EnableAsync
public class MyConfig {
    @Bean("myThreadPool")
    public Executor getExecutor() {
        ThreadFactory namedThreadFactory = r -> {
            Thread thread = new Thread(r);
            thread.setName("myThreadPool");
            return thread;
        };
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        //             
        executor.setCorePoolSize(5);
        //             
        executor.setMaxPoolSize(10);
        //     
        executor.setQueueCapacity(25);
        //   
        executor.setThreadFactory(namedThreadFactory);
        //       
        executor.initialize();
        return executor;
    }
}
モニターメソッドに@Asyncコメントを追加し、自分で定義したExectorを指定します.
/**
 *       (   )
 */
@Component
public class MyListener   {
    @Async("myThreadPool")
    @EventListener
    public void reciveMsg(MyEvent myEvent){
        String msg = (String) myEvent.getSource();
        System.out.println(Thread.currentThread().getName()+ ": recive msg --"+msg);
    }
}