我需要一个CDI可注射的KieContainer,它使用KieScanner在将新规则包添加到maven存储库时更新规则。下面的方法工作正常,但它会泄漏内存,因为每次注入KieContainer时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");
}
}
答案 0 :(得分:0)
简短回答:在制作人方法上使用范围。生产者方法可以指定生成的bean的范围。 cdi specification
中明确说明了这一点答案很长:
如果KieContainer是可重用对象并且所有bean共享一个实例是安全的,请考虑使用@ApplicationScoped
注释您的生产者方法。请注意@Singleton
和@ApplicationScoped之间存在差异。另请注意我说的是生成器方法,而不是生成器bean类。
如果KieContainer不可重复使用,但内部KieScanner是,则创建另一个使用@ApplicationScoped
注释的生产者方法,并将该KieScanner注入KieContainer方法。它将被重用。
@Dependent
注释您当前的制作人类。