Maven 如何使用KieScanner创建KieContainer生产者?

Maven 如何使用KieScanner创建KieContainer生产者?,maven,jakarta-ee,cdi,drools,kie,Maven,Jakarta Ee,Cdi,Drools,Kie,我需要一个CDI可注入的KieContainer,当一个新的规则包被添加到maven存储库时,它使用KieScanner来更新规则。下面的方法工作正常,但是它正在泄漏内存,因为每次注入KieScanner容器时,KieScanner都会创建一个新的TimerService。如何使用KieScanner创建一个KieContainer生产者方法,而不是为注入的每个KieContainer启动一个新的KieScanner @Slf4j @Singleton public class KieConta

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

@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");
    }

}

简短回答:在生产者方法上使用作用域。Producer方法可以指定生成的bean的范围。这一点在本文件中有明确说明

长答案

<> LI> < P>如果KieCeNeRever是可重用对象,所有bean共享一个实例都是安全的,请考虑用<代码> @ Apple PosikSimule注释生产者方法。请注意,
@Singleton
和@ApplicationScoped之间存在差异。另外请注意,我谈论的是producer方法,而不是producerbean类

  • 如果KieContainer是不可重用的,但内部KieCandscanner是可重用的,请创建另一个用
    @ApplicationScoped
    注释的生产者方法,并将该KieCandscanner注入KieContainer方法。它将被重新使用

  • <> LI>如果两者都不能重复使用,请考虑用<代码> @ Actudio< <代码>注释您当前的生产者类。
    您是否尝试过跟踪当前KieScanner并在重新创建新KieContainer时对其调用
    shutdown()
    ?没有尝试过,但也在考虑该解决方案。不过,这感觉像是一种解决方法,因为您仍在不断启动和停止扫描仪。在我看来,单例扫描程序应该只是在后台运行,在启动时创建,并且只有在由于某种原因bean被破坏的情况下才重新创建。你想让我写一个答案,说如果只有一种方法可以做到这一点,那么这种方法不是一种解决方法;-)?如果每个新容器都需要一个新的扫描仪,那么就这样。可能有一个很好的理由不能在运行的扫描仪内交换容器,但我不知道。你可以在口水清单上问这个问题。我不需要为每个容器安装新的扫描仪。但是,我确实需要一个从maven存储库更新的可注入容器。也许我完全不知道工厂的结构。。。