千家信息网

dubbo中AwaitingNonWebApplicationListener的实例介绍

发表于:2025-01-24 作者:千家信息网编辑
千家信息网最后更新 2025年01月24日,本篇内容主要讲解"dubbo中AwaitingNonWebApplicationListener的实例介绍",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"d
千家信息网最后更新 2025年01月24日dubbo中AwaitingNonWebApplicationListener的实例介绍

本篇内容主要讲解"dubbo中AwaitingNonWebApplicationListener的实例介绍",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"dubbo中AwaitingNonWebApplicationListener的实例介绍"吧!

本文主要研究一下dubbo的AwaitingNonWebApplicationListener

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[] 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 static  T[] of(T... values) {        return values;    }    static AtomicBoolean getAwaited() {        return awaited;    }    @Override    public boolean supportsEventType(Class 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

AwaitingNonWebApplicationListenerTest

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的实例介绍"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

0