ApplicationListener系列文章
观察者模式
根据上述UML图,可以把Event看做被观察者,Listener看做观察者。但是被观察者的addObserver、deleteObserver、notifyObserver通过转发器(SimpleApplicationEventMulticaster)进行处理。但是整体的设计还是按照观察者模式设计。
ApplicationListenerDetector
通过ApplicationListenerDetector实现,以后的开发中,也可以参考Detector的形式,把发现(ApplicationListenerDetector)和持有(AbstractApplicationListener)分开处理。例如:key=value形式的对象持有,可以把发现和持有拆分。
例如:
public class SmsSenderRegistry {
private static Map<String, SmsSender> SENDER_MAP = new HashMap<>();
public static void register(SmsSender sender) {
SENDER_MAP.put(sender.provider(), sender);
}
public static SmsSender getSender(String provider) {
return SENDER_MAP.get(provider);
}
public static void remove(SmsSender bean) {
SENDER_MAP.remove(bean);
}
}
public class SmsSenderDetector implements MergedBeanDefinitionPostProcessor,
DestructionAwareBeanPostProcessor {
private final transient Map<String, Boolean> singletonNames = new ConcurrentHashMap<>(256);
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
if (ApplicationListener.class.isAssignableFrom(beanType)) {
this.singletonNames.put(beanName, beanDefinition.isSingleton());
}
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
if (bean instanceof SmsSender) {
Boolean flag = this.singletonNames.get(beanName);
if (Boolean.TRUE.equals(flag)) {
SmsSenderRegistry.register((SmsSender) bean);
} else if (Boolean.FALSE.equals(flag)) {
this.singletonNames.remove(beanName);
}
}
return bean;
}
@Override
public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
if (bean instanceof SmsSender) {
try {
SmsSenderRegistry.remove((SmsSender) bean);
} catch (IllegalStateException ex) {
// ApplicationEventMulticaster not initialized yet - no need to remove a listener
}
}
}
}
public interface SmsSender {
String provider();
void sendSms(String msg);
}
public class JiGuangSmsSender implements SmsSender{
@Override
public String provider() {
return null;
}
@Override
public void sendSms(String msg) {
}
}
public class GeTuiSmsSender implements SmsSender{
@Override
public String provider() {
return null;
}
@Override
public void sendSms(String msg) {
}
}
当然上述也可以用@Autowired Map<String,SmsSender> senderMap; 注入到业务中。
缺陷
-
高并发:大批量的通过发送事件,实现进行业务解耦,那么建议用MQ比较合适。
-
可靠性:事件无法固话,系统一旦重启,已经发送还未完成执行完的事件就消失了,请注意使用。
-
干扰性:每个监听,必须进行相关的try catch,防止当前监听的异常,影响其他监听,可以考虑线程池。