ApplicationListener是Spring事件机制的一部分,与抽象类ApplicationEvent类配合来完成ApplicationContext的事件发布订阅机制。
ApplicationEventpackage com.example.demo.event;
import org.springframework.context.ApplicationEvent;
public class ObjectVo extends ApplicationEvent {
private String message;
public ObjectVo(Object source, String message) {
super(source);
this.message = message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
定义监听器处理类1,这里使用注解@EventListener
package com.example.demo.event;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Component
@Order(2)
public class HandlerListener {
@EventListener
public void listen(ObjectVo source) {
System.out.println(this.getClass().getName() + " " + source.getMessage());
}
}
定义监听器处理类2
package com.example.demo.event;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Component
@Order(1)
public class HandlerListener2 {
@EventListener
public void listen(ObjectVo source) {
System.out.println(this.getClass().getName() + " " + source.getMessage());
}
}
发布事件处理类:
package com.example.demo.event;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;
@Component
public class ListenEventPubliserService {
@Autowired
private ApplicationEventPublisher publisher;
public void publisher() {
String message = "hello publisher";
ObjectVo objectVo = new ObjectVo(this, message);
publisher.publishEvent(objectVo);
}
}
运行结果:
可以看到两个Listener都分别接收到了事件。
这里发现一个问题:我在两个Listener类加了@Order注解,理论上值越小的越应该先执行对吧?但是上面输出结果来看,并不是我们期望的这样,而是HandlerListener先输出了,Order不生效了?
经查阅文章后了解到,Spring中的Order接口只针对AOP切面和拦截器以及注入集合中的bean执行顺序,而对于bean加载顺序是不会干预的,也就是默认文件顺序了。
那么怎么办呢,如果我们一定要HandlerListener2先执行的话,怎么做?
上面说了,bean依赖注入集合执行顺序它能控制,那么我们使用集合的思路不就行了吗?
于是将上面代码做以下调整;
package com.example.demo.event; import org.springframework.context.ApplicationListener; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Service; @Service @Order(1) public class HandlerListener2 implements ApplicationListener{ public HandlerListener2() { System.out.println("加载" + this.getClass().getName()); } @Override public void onApplicationEvent(ObjectVo source) { System.out.println(this.getClass().getName() + " " + source.getMessage()); } }
package com.example.demo.event; import org.springframework.context.ApplicationListener; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Service; @Service @Order(2) public class HandlerListener implements ApplicationListener{ public HandlerListener() { System.out.println("加载" + this.getClass().getName()); } @Override public void onApplicationEvent(ObjectVo source) { System.out.println(this.getClass().getName() + " " + source.getMessage()); } }
再次执行结果:
可以看到HandlerListener2先执行了。
因为拿Listener时候,spring做了下排序,参考类的方法
org.springframework.context.event.AbstractApplicationEventMulticaster#retrieveApplicationListeners
private Collection> retrieveApplicationListeners( ResolvableType eventType, @Nullable Class> sourceType, @Nullable ListenerRetriever retriever) { List > allListeners = new ArrayList<>(); Set > listeners; Set listenerBeans; synchronized (this.retrievalMutex) { listeners = new linkedHashSet<>(this.defaultRetriever.applicationListeners); listenerBeans = new linkedHashSet<>(this.defaultRetriever.applicationListenerBeans); } for (ApplicationListener> listener : listeners) { if (supportsEvent(listener, eventType, sourceType)) { if (retriever != null) { retriever.applicationListeners.add(listener); } allListeners.add(listener); } } if (!listenerBeans.isEmpty()) { BeanFactory beanFactory = getBeanFactory(); for (String listenerBeanName : listenerBeans) { try { Class> listenerType = beanFactory.getType(listenerBeanName); if (listenerType == null || supportsEvent(listenerType, eventType)) { ApplicationListener> listener = beanFactory.getBean(listenerBeanName, ApplicationListener.class); if (!allListeners.contains(listener) && supportsEvent(listener, eventType, sourceType)) { if (retriever != null) { if (beanFactory.isSingleton(listenerBeanName)) { retriever.applicationListeners.add(listener); } else { retriever.applicationListenerBeans.add(listenerBeanName); } } allListeners.add(listener); } } } catch (NoSuchBeanDefinitionException ex) { // Singleton listener instance (without backing bean definition) disappeared - // probably in the middle of the destruction phase } } } AnnotationAwareOrderComparator.sort(allListeners); if (retriever != null && retriever.applicationListenerBeans.isEmpty()) { retriever.applicationListeners.clear(); retriever.applicationListeners.addAll(allListeners); } return allListeners; }
其中有一句:
AnnotationAwareOrderComparator.sort(allListeners);



