0

我有一个非常简单的 Java Weld SE 应用程序。根据文档, Weld 注册了一个应该挂钩以正确关闭容器。我希望它会尝试正确关闭所有托管 bean,但似乎容器会立即完成。

简单的 CDI bean:

@ApplicationScoped
public class CDIBean {
    private static final Logger logger = Logger.getLogger(CDIBean.class.getName());
    private AtomicBoolean keepRunning;
    private CountDownLatch threadFinished;

    public void start(@Observes ContainerInitialized event) {
        logger.log(Level.INFO, "start");
    }

    @PostConstruct
    public void postConstruct() {
        logger.log(Level.INFO, "postConstruct");
        keepRunning = new AtomicBoolean(true);
        threadFinished = new CountDownLatch(1);
        new Thread(() -> {
            while (keepRunning.get()) {
                try {
                    logger.log(Level.INFO, "Still running...");
                    Thread.sleep(200);
                } catch (InterruptedException ie) {
                    throw new RuntimeException(ie);
                }
            }
            threadFinished.countDown();;
        }).start();
    }

    @PreDestroy
    public void preDestroy() {
        logger.log(Level.INFO, "preDestroy");
        keepRunning.set(false);
        try {
            threadFinished.await();
        } catch (InterruptedException ie) {
            throw new RuntimeException(ie);
        }
    }
}

主要:

public class Main {
    public static void main(String[] args) {
        Weld weld = new Weld();
        WeldContainer container = weld.beanClasses(CDIBean.class)
                .disableDiscovery().initialize();
    }
}

控制台输出(应用程序以CTRL+Cor结尾kill -15,两者的结果相同):

INFO: WELD-000900: 3.1.3 (Final)
INFO: WELD-000101: Transactional services not available. Injection of @Inject UserTransaction not available. Transactional observers will be invoked synchronously.
INFO: WELD-ENV-002003: Weld SE container 07a30136-de8f-47f9-ad5f-fbdf85cc5b60 initialized
INFO: postConstruct
INFO: start
INFO: Still running...
INFO: Still running...
INFO: Still running...
INFO: Still running...
INFO: Still running...
INFO: Still running...
^CWeld SE container 07a30136-de8f-47f9-ad5f-fbdf85cc5b60 shut down by shutdown hook

container.close()但是,如果使用终止程序以编程方式关闭容器,则可以正常工作:

.
.
.
INFO: Still running...
INFO: Still running...
INFO: preDestroy
INFO: WELD-ENV-002001: Weld SE container 999543ef-ae42-4617-8536-329412f3a9c7 shut down

所以我的问题是:如何让容器在SIGTERM收到时优雅地关闭?内置的关闭钩子不会这样做......

4

1 回答 1

3

好吧,好吧,好吧-不是Weld,而是记录器让我感到困惑。SIGTERM内置的关闭挂钩按预期工作,但记录器在收到后停止登录控制台。因此,如果我将 @PreDestroy 方法的主体更改为简单,System.out.println("preDestroy");那么它会在控制台中显示为一个魅力。

于 2019-12-06T14:19:11.133 回答