接着之前的事件监听机制实现,我们可以进一步优化。从以下两个方面:
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,不然不能覆盖原先的事件广播器,起不到覆盖的作用。
结果如下:
这样支线任务就采用多线程的方式实现。