? ? ? 接著之前的事件監聽機制實現,我們可以進一步優化。從以下兩個方面:
? ? ?1.使用@EventListener注解
@Configuration
public class TestListener2 {public static void main(String[] args) {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(TestListener2.class);context.getBean(MyService.class).doBusiness();context.close();}static class MyEvent extends ApplicationEvent {public MyEvent(Object source) {super(source);}}@Componentstatic class MyService{private static final Logger log = LoggerFactory.getLogger(TestListener2.class);@Autowiredprivate ApplicationEventPublisher publisher;public void doBusiness(){log.debug("主線業務");/* log.debug("發送短信");log.debug("發送郵件");*/publisher.publishEvent(new MyEvent("MyService.doBusiness()"));}}@Componentstatic class SmsService{private static final Logger log = LoggerFactory.getLogger(SmsService.class);@EventListenerpublic void listener(MyEvent event) {log.debug("發送短信");}}@Componentstatic class EmailService{private static final Logger log = LoggerFactory.getLogger(EmailService.class);@EventListenerpublic void listener(MyEvent event) {log.debug("發送郵件");}}
打印結果:
? ?2.采用多線程的方式
? ? (1)首先定義一個任務執行器
? ? ? ? ? ? ?設置線程池的對應參數
@Beanpublic ThreadPoolTaskExecutor executor(){ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(3);executor.setMaxPoolSize(10);executor.setQueueCapacity(100);return executor;}
? (2)注入SimpleApplicationEventMulticaster對象
? ? ? ? ?Spring是使用SimpleApplicationEventMulticaster對象廣播事件的,默認是同步實現,其中有一個屬性是Executor對象,可以替換為上面我們自己注入的Bean對象,實現多線程廣播。
@Beanpublic SimpleApplicationEventMulticaster applicationEventMulticaster(ThreadPoolTaskExecutor executor){SimpleApplicationEventMulticaster multicaster = new SimpleApplicationEventMulticaster();multicaster.setTaskExecutor(executor);return multicaster;}
? ? ? ?其中方法名必須為applicationEventMulticaster,不然不能覆蓋原先的事件廣播器,起不到覆蓋的作用。
結果如下:
這樣支線任務就采用多線程的方式實現。