我在Java中有一个Singleton类,我有一个使用@Schedule注解的计时器。我希望在运行时更改计划的属性。下面是代码:
@Startup
@Singleton
public class Listener {
public void setProperty() {
Method[] methods = this.getClass().getDeclaredMethods();
Method method = methods[0];
Annotation[] annotations = method.getDeclaredAnnotations();
Annotation annotation = annotations[0];
if(annotation instanceof Schedule) {
Schedule schedule = (Schedule) annotation;
System.out.println(schedule.second());
}
}
@PostConstruct
public void runAtStartUp() {
setProperty();
}
@Schedule(second = "3")
public void run() {
// do something
}
}
我希望根据属性文件中的信息在运行时更改计划秒的值。这真的有可能吗?属性文件包含配置信息。我尝试做@Schedule(秒 = SOME_VARIABLE),其中私有静态字符串 SOME_VARIABLE = readFromConfigFile();这行不通。它期望一个常量意味着一个决赛,我不想设置决赛。
我还看到了这篇文章:在java中修改运行时的注释属性值
这表明这是不可能的。
有什么想法吗?
编辑:
@Startup
@Singleton
public class Listener {
javax.annotation.@Resource // the issue is this
private javax.ejb.TimerService timerService;
private static String SOME_VARIABLE = null;
@PostConstruct
public void runAtStartUp() {
SOME_VARIABLE = readFromFile();
timerService.createTimer(new Date(), TimeUnit.SECONDS.toMillis(Long.parse(SOME_VARIABLE)), null);
}
@Timeout
public void check(Timer timer) {
// some code runs every SOME_VARIABLE as seconds
}
}
问题是使用@Resource注入。如何解决这个问题?
异常如下所示:
No EJBContainer provider available The following providers: org.glassfish.ejb.embedded.EJBContainerProviderImpl Returned null from createEJBContainer call
javax.ejb.EJBException
org.glassfish.ejb.embedded.EJBContainerProviderImpl
at javax.ejb.embeddable.EJBContainer.reportError(EJBContainer.java:186)
at javax.ejb.embeddable.EJBContainer.createEJBContainer(EJBContainer.java:121)
at javax.ejb.embeddable.EJBContainer.createEJBContainer(EJBContainer.java:78)
@BeforeClass
public void setUpClass() throws Exception {
Container container = EJBContainer.createEJBContainer();
}
这在使用可嵌入的 EJB 容器进行单元测试期间发生。一些Apache Maven代码位于这篇文章中:Java EJB JNDI Beans Lookup Failed
我认为您正在寻找的解决方案已在此处讨论。
TomasZ 是对的,您应该将编程计时器与 TimerService 结合使用,以应对您希望在运行时动态更改计划的情况。
也许您可以使用TimerService
.我已经编写了一些代码,但在我的 Wildfly 8 上,即使它是单例,它似乎也会运行多次。文档 http://docs.oracle.com/javaee/6/tutorial/doc/bnboy.html
希望这有帮助:
@javax.ejb.Singleton
@javax.ejb.Startup
public class VariableEjbTimer {
@javax.annotation.Resource
javax.ejb.TimerService timerService;
@javax.annotation.PostConstruct
public void runAtStartUp() {
createTimer(2000L);
}
private void createTimer(long millis) {
//timerService.createSingleActionTimer(millis, new javax.ejb.TimerConfig());
timerService.createTimer(millis, millis, null);
}
@javax.ejb.Timeout
public void run(javax.ejb.Timer timer) {
long timeout = readFromConfigFile();
System.out.println("Timeout in " + timeout);
createTimer(timeout);
}
private long readFromConfigFile() {
return new java.util.Random().nextInt(5) * 1000L;
}
}