接着之前的事件监听机制实现,我们可以进一步优化。从以下两个方面:
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);
}
}
@Component
static class MyService{
private static final Logger log = LoggerFactory.getLogger(TestListener2.class);
@Autowired
private ApplicationEventPublisher publisher;
public void doBusiness(){
log.debug("主线业务");
/* log.debug("发送短信");
log.debug("发送邮件");*/
publisher.publishEvent(new MyEvent("MyService.doBusiness()"));
}
}
@Component
static class SmsService{
private static final Logger log = LoggerFactory.getLogger(SmsService.class);
@EventListener
public void listener(MyEvent event) {
log.debug("发送短信");
}
}
@Component
static class EmailService{
private static final Logger log = LoggerFactory.getLogger(EmailService.class);
@EventListener
public void listener(MyEvent event) {
log.debug("发送邮件");
}
}
打印结果:
2.采用多线程的方式
(1)首先定义一个任务执行器
设置线程池的对应参数
@Bean
public ThreadPoolTaskExecutor executor(){
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(3);
executor.setMaxPoolSize(10);
executor.setQueueCapacity(100);
return executor;
}
(2)注入SimpleApplicationEventMulticaster对象
Spring是使用SimpleApplicationEventMulticaster对象广播事件的,默认是同步实现,其中有一个属性是Executor对象,可以替换为上面我们自己注入的Bean对象,实现多线程广播。
@Bean
public SimpleApplicationEventMulticaster applicationEventMulticaster(ThreadPoolTaskExecutor executor){
SimpleApplicationEventMulticaster multicaster = new SimpleApplicationEventMulticaster();
multicaster.setTaskExecutor(executor);
return multicaster;
}
其中方法名必须为applicationEventMulticaster,不然不能覆盖原先的事件广播器,起不到覆盖的作用。
结果如下:
这样支线任务就采用多线程的方式实现。