【问题标题】:How to create a KieContainer producer using the KieScanner?如何使用 KieScanner 创建 KieContainer 生产者?
【发布时间】:2017-06-07 13:27:28
【问题描述】:

我需要一个可注入 CDI 的 KieContainer,它在将新规则包添加到 maven 存储库时使用 KieScanner 更新规则。下面的方法工作正常,但是它会泄漏内存,因为每次注入 KieContainer 时 KieScanner 都会创建一个新的 TimerService。如何使用不会为每个注入的 KieContainer 启动新的 KieScanner 的 KieScanner 创建 KieContainer 生产者方法?

@Slf4j
@Singleton
public class KieContainerProducer {

    private static final String PROPERTIES_FILENAME = "scanner.properties";

    @Produces
    public static KieContainer produceContainer() {
        try {
            ClassLoader loader = Thread.currentThread().getContextClassLoader();
            Properties properties = new Properties();
            try (InputStream is = loader.getResourceAsStream(PROPERTIES_FILENAME)) {
                properties.load(is);
            }
            KieServices ks = KieServices.get();
            ReleaseId releaseId = ks.newReleaseId(
                    properties.getProperty("groupId"),
                    properties.getProperty("artifactId"),
                    properties.getProperty("version"));
            KieContainer kContainer = ks.newKieContainer(releaseId);
            KieScanner kScanner = ks.newKieScanner(kContainer);
            kScanner.start(60000L);
            return kContainer;
        } catch (FileNotFoundException ex) {
            log.error("Properties file scanner.properties not found.");
            log.debug("FileNotFoundException: ", ex);
        } catch (IOException ex) {
            log.error("{} file not found.", PROPERTIES_FILENAME);
            log.debug("IOException", ex);
        }
        throw new IllegalStateException("There was an error in the KieContainerProducer");
    }

}

【问题讨论】:

  • 您是否尝试过跟踪当前的 KieScanner 并在重新创建新的 KieContainer 时调用shutdown()
  • 没试过,但也在考虑那个解决方案。然而,这感觉是一种解决方法,因为您仍在不断地启动和停止扫描仪。在我看来,单例扫描仪应该只是在后台运行,在启动时创建,并且只有在由于某种原因 bean 被销毁时才重新创建
  • 您是否希望我写一个答案,说如果只有一种方法可以做到这一点,那么这种方法就不是一种解决方法;-)?如果您需要为每个新容器配备一个新的扫描仪,那么就是这样。无法在正在运行的扫描仪中交换容器可能有充分的理由,但我不知道。你可能会在 Drools 列表上问这个问题。
  • 我不需要为每个容器安装新的扫描仪。但是,我确实需要一个从 maven 存储库更新的可注入 KieContainer。也许我完全迷失了 KieServices 工厂的结构......

标签: maven jakarta-ee cdi drools kie


【解决方案1】:

简答:在生产者方法上使用范围。生产者方法可以指定生产的 bean 的范围。这在cdi specification中有明确说明

长答案

  1. 如果 KieContainer 是可重用对象并且所有 bean 共享一个实例是安全的,请考虑使用 @ApplicationScoped 注释您的生产者方法。请注意@Singleton 和@ApplicationScoped 之间存在差异。另请注意,我说的是生产者方法,而不是生产者 bean 类。

  2. 如果 KieContainer 不可重用,但内部 KieScanner 可重用,则创建另一个使用 @ApplicationScoped 注释的生产者方法,并将该 KieScanner 注入 KieContainer 方法。它将被重复使用。

  3. 如果两者都不能重用,请考虑使用 @Dependent 注释您当前的生产者类。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-09
    • 2023-01-09
    • 2019-07-22
    • 1970-01-01
    • 1970-01-01
    • 2021-09-03
    相关资源
    最近更新 更多