gpt4 book ai didi

java - JSF 每 2 秒从系统动态加载属性文件

转载 作者:行者123 更新时间:2023-11-30 09:15:46 25 4
gpt4 key购买 nike

我正在尝试使用 @ApplicationScoped @ManagedBean 调用和计划任务,每 2 秒将一些属性加载到我的 JSF 应用程序中。出于某种原因不是在职的。请参阅我遵循的步骤。

我做的第一件事是创建一个类,每 2 秒从文件系统加载一次:

@ManagedBean
@ApplicationScoped
public class ProppertyReader {


@PostConstruct
public void init(){
SystemReader systemReader = new SystemReader();
systemReader.schedule();
}

private class SystemReader {
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
private Logger LOGGER = Logger.getLogger(ProppertyReader.class.getName());

public void schedule(){
scheduler.scheduleAtFixedRate(new Runnable() {
public void run() {
Properties properties = loadProperties();
LOGGER.info("Loaded property enabled:" + properties.getProperty("enabled"));
}
}, 0L, 2L, TimeUnit.SECONDS);
}

private Properties loadProperties() {
try {
Properties properties = new Properties();
properties.load(new FileInputStream("~/Desktop/propertiesRepo/example.properties"));
return properties;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
}

然后我转到另一个 bean 并尝试使用该属性:

@ManagedBean
@SessionScoped
public class SomeBean {
//...
private Properties properties = new Properties();
private boolean enabled = new Boolean(properties.getProperty("enabled"));
//...
public boolean isEnabled() {
return enabled;
}
}

当我尝试在 JSF if 语句中使用一些使用 #{someBean.enabled} 的 bean 来根据该值显示或隐藏组件时,似乎不起作用:

<c:if test="#{someBean.enabled}">
<h1>Works!</h1>
</c:if>

我不知道哪里出了问题,知道吗?

更新:我看到了 Properties 类的错误。我现在正在尝试创建那些未被处置的属性,因此我清理了一些代码,但在应用程序启动时我得到了一个 NullPointer。

我将属性阅读器分为两类:

@ManagedBean
@ApplicationScoped
public class ProppertyReader {

private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
private SystemReader systemReader = new SystemReader();
public static Properties appProperties;

@PostConstruct
public void init(){
schedule();
}

private void schedule(){
scheduler.scheduleAtFixedRate(new Runnable() {
public void run() {
appProperties = systemReader.loadProperties();
}
}, 0L, 2L, TimeUnit.SECONDS);
}
}

这里是我从系统读取数据的地方:

public class SystemReader {

public Properties loadProperties() {
try {
Properties properties = new Properties();
properties.load(new FileInputStream("~/Desktop/propertiesRepo/example.properties"));
return properties;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}

我现在的称呼方式是:

@ManagedBean
@SessionScoped
public class SomeBean {

private boolean enabled = new Boolean(ProppertyReader.appProperties.getProperty("enabled"));
//...

目前我收到 NullPointer 异常,我想我已经接近了。

最佳答案

这不是 Java 的工作方式。

为了实现您的目标,您应该将属性文件保存为应用程序作用域 bean 的实例变量,并且每次都重新加载其内容,而不是每次都重新创建和丢弃(!!)它。您不应该在 session 作用域 bean 中创建一个完全独立的属性类实例,而应该使用应用程序作用域 bean 中的实例。

这里是一个重写:

@ManagedBean
@ApplicationScoped
public class PropertiesHolder {

private static final String PATH = "~/Desktop/propertiesRepo/example.properties";
private Properties properties;
private ScheduledExecutorService scheduler;

@PostConstruct
public void init() {
properties = new Properties();
scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
try {
properties.load(new FileInputStream(PATH));
} catch (IOException e) {
throw new RuntimeException("Failed to load properties", e);
}
}
}, 0L, 2L, TimeUnit.SECONDS);
}

@PreDestroy
public void destroy() {
scheduler.shutdownNow();
}

public String getProperty(String key) {
return properties.getProperty(key);
}

}

请注意,我还添加了一个 @PreDestroy 来关闭调度程序,否则您可能会在每次服务器重新启动时泄漏线程,直到 Java 运行时环境用完线程。

如果您想获得最新的值,您应该如何在 session 范围的 bean 中使用它:

@ManagedBean
@SessionScoped
public class SomeBean {

@ManagedProperty("#{propertiesHolder}")
private PropertiesHolder propertiesHolder;

public void setPropertiesHolder(PropertiesHolder propertiesHolder) {
this.propertiesHolder = propertiesHolder;
}

public boolean isEnabled() {
return new Boolean(propertiesHolder.getProperty("enabled"));
}

}

请注意,该属性不是在 bean 实例化时获得的,否则您将在每次 getter 调用时只获得 bean 实例化时的值,而永远不会在同一 session 中的后续请求中获得更新后的值。

更重要的是,该值本质上是请求范围的,因此 session 范围只是保存该值的错误范围。改为将其设为请求范围的 bean:

@ManagedBean
@RequestScoped
public class SomeBean {

@ManagedProperty("#{propertiesHolder.getProperty('enabled')}")
private boolean enabled;

public boolean isEnabled() {
return enabled;
}

public void setEnabled(boolean enabled) {
this.enabled = enabled;
}

}

关于java - JSF 每 2 秒从系统动态加载属性文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19741124/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com