ApplicationListener是Spring事件机制的一部分,与抽象类ApplicationEvent类配合来完成ApplicationContext的事件发布订阅机制。
ApplicationEvent
package com.example.demo.event;
import org.springframework.context.ApplicationEvent;
/**
* @author huangd
* @date 2021-11-09
**/
public class ObjectVo extends ApplicationEvent {
private String message;
/**
* Create a new ApplicationEvent.
*
* @param source the object on which the event initially occurred (never {@code null})
*/
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;
/**
* @author huangd
* @date 2021-11-10
**/
@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;
/**
* @author huangd
* @date 2021-11-10
**/
@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;
/**
* @author huangd
* @date 2021-11-10
**/
@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;
/**
* @author huangd
* @date 2021-11-10
**/
@Service
@Order(1)
public class HandlerListener2 implements ApplicationListener<ObjectVo> {
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;
/**
* @author huangd
* @date 2021-11-10
**/
@Service
@Order(2)
public class HandlerListener implements ApplicationListener<ObjectVo> {
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<ApplicationListener<?>> retrieveApplicationListeners(
ResolvableType eventType, @Nullable Class<?> sourceType, @Nullable ListenerRetriever retriever) {
List<ApplicationListener<?>> allListeners = new ArrayList<>();
Set<ApplicationListener<?>> listeners;
Set<String> 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);