本篇内容主要讲解“dubbo中AwaitingNonWebApplicationListener的实例介绍”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“dubbo中AwaitingNonWebApplicationListener的实例介绍”吧!
创新互联主营侯马网站建设的网络公司,主营网站建设方案,APP应用开发,侯马h5微信平台小程序开发搭建,侯马网站营销推广欢迎侯马等地区企业咨询
本文主要研究一下dubbo的AwaitingNonWebApplicationListener
public class AwaitingNonWebApplicationListener implements SmartApplicationListener { private static final String[] WEB_APPLICATION_CONTEXT_CLASSES = new String[]{ "org.springframework.web.context.WebApplicationContext", "org.springframework.boot.web.reactive.context.ReactiveWebApplicationContext" }; private static final Logger logger = LoggerFactory.getLogger(AwaitingNonWebApplicationListener.class); private static final Class extends ApplicationEvent>[] SUPPORTED_APPLICATION_EVENTS = of(ApplicationReadyEvent.class, ContextClosedEvent.class); private static final AtomicBoolean awaited = new AtomicBoolean(false); private static final Lock lock = new ReentrantLock(); private static final Condition condition = lock.newCondition(); private static final ExecutorService executorService = newSingleThreadExecutor(); private staticT[] of(T... values) { return values; } static AtomicBoolean getAwaited() { return awaited; } @Override public boolean supportsEventType(Class extends ApplicationEvent> eventType) { return containsElement(SUPPORTED_APPLICATION_EVENTS, eventType); } @Override public boolean supportsSourceType(Class> sourceType) { return true; } @Override public void onApplicationEvent(ApplicationEvent event) { if (event instanceof ApplicationReadyEvent) { onApplicationReadyEvent((ApplicationReadyEvent) event); } else if (event instanceof ContextClosedEvent) { onContextClosedEvent((ContextClosedEvent) event); } } @Override public int getOrder() { return LOWEST_PRECEDENCE; } protected void onApplicationReadyEvent(ApplicationReadyEvent event) { final ConfigurableApplicationContext applicationContext = event.getApplicationContext(); if (!isRootApplicationContext(applicationContext) || isWebApplication(applicationContext)) { return; } await(); } private boolean isRootApplicationContext(ApplicationContext applicationContext) { return applicationContext.getParent() == null; } private boolean isWebApplication(ApplicationContext applicationContext) { boolean webApplication = false; for (String contextClass : WEB_APPLICATION_CONTEXT_CLASSES) { if (isAssignable(contextClass, applicationContext.getClass(), applicationContext.getClassLoader())) { webApplication = true; break; } } return webApplication; } private static boolean isAssignable(String target, Class> type, ClassLoader classLoader) { try { return ClassUtils.resolveClassName(target, classLoader).isAssignableFrom(type); } catch (Throwable ex) { return false; } } protected void onContextClosedEvent(ContextClosedEvent event) { release(); shutdown(); } protected void await() { // has been waited, return immediately if (awaited.get()) { return; } if (!executorService.isShutdown()) { executorService.execute(() -> executeMutually(() -> { while (!awaited.get()) { if (logger.isInfoEnabled()) { logger.info(" [Dubbo] Current Spring Boot Application is await..."); } try { condition.await(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } })); } } protected void release() { executeMutually(() -> { while (awaited.compareAndSet(false, true)) { if (logger.isInfoEnabled()) { logger.info(" [Dubbo] Current Spring Boot Application is about to shutdown..."); } condition.signalAll(); } }); } private void shutdown() { if (!executorService.isShutdown()) { // Shutdown executorService executorService.shutdown(); } } private void executeMutually(Runnable runnable) { try { lock.lock(); runnable.run(); } finally { lock.unlock(); } } }
AwaitingNonWebApplicationListener实现了SmartApplicationListener接口,其supportsEventType支持ApplicationReadyEvent.class, ContextClosedEvent.class
onApplicationEvent判断是ApplicationReadyEvent时执行onApplicationReadyEvent方法;判断是ContextClosedEvent时,执行onContextClosedEvent方法
onApplicationReadyEvent对于rootApplicationContext或者是nonWebApplicationContext执行await方法,该方法会注册一个异步线程去执行condition.await();onContextClosedEvent则执行release及shutdown方法,release方法会更新awaited为true,然后执行condition.signalAll(),shutdown方法则关闭executorService
dubbo-spring-boot-project-2.7.3/dubbo-spring-boot-compatible/autoconfigure/src/test/java/org/apache/dubbo/spring/boot/context/event/AwaitingNonWebApplicationListenerTest.java
public class AwaitingNonWebApplicationListenerTest { @Test public void init() { AtomicBoolean awaited = AwaitingNonWebApplicationListener.getAwaited(); awaited.set(false); } @Test public void testSingleContextNonWebApplication() { new SpringApplicationBuilder(Object.class) .web(false) .run().close(); AtomicBoolean awaited = AwaitingNonWebApplicationListener.getAwaited(); Assert.assertTrue(awaited.get()); } @Test public void testMultipleContextNonWebApplication() { new SpringApplicationBuilder(Object.class) .parent(Object.class) .web(false) .run().close(); AtomicBoolean awaited = AwaitingNonWebApplicationListener.getAwaited(); Assert.assertTrue(awaited.get()); } }
AwaitingNonWebApplicationListenerTest验证了SingleContextNonWebApplication及MultipleContextNonWebApplication
AwaitingNonWebApplicationListener实现了SmartApplicationListener接口,其supportsEventType支持ApplicationReadyEvent.class, ContextClosedEvent.class
onApplicationEvent判断是ApplicationReadyEvent时执行onApplicationReadyEvent方法;判断是ContextClosedEvent时,执行onContextClosedEvent方法
onApplicationReadyEvent对于rootApplicationContext或者是nonWebApplicationContext执行await方法,该方法会注册一个异步线程去执行condition.await();onContextClosedEvent则执行release及shutdown方法,release方法会更新awaited为true,然后执行condition.signalAll(),shutdown方法则关闭executorService
到此,相信大家对“dubbo中AwaitingNonWebApplicationListener的实例介绍”有了更深的了解,不妨来实际操作一番吧!这里是创新互联网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!