我在Java中有一个Singleton类,我有一个使用@Schedule注释的计时器。我希望在运行时更改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
}
}
我希望根据Property文件中的信息更改Schedule second运行时的值。这实际上是可能的吗? Property文件包含配置信息。我试图做@Schedule(second = SOME_VARIABLE),其中私有静态String SOME_VARIABLE = readFromConfigFile();这不起作用。它期望决赛具有恒定意义,我不想设定决赛。
我也看过这篇文章:Modifying annotation attribute value at runtime in 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();
}
在使用Embeddable EJB Container进行单元测试期间会发生这种情况。一些Apache Maven代码位于此帖子:Java EJB JNDI Beans Lookup Failed
答案 0 :(得分:0)
也许你可以使用TimerService
。我已经编写了一些代码但是在我的Wildfly 8上它似乎运行了多次,即使它是一个Singleton。
文档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;
}
}
答案 1 :(得分:0)
我认为您正在寻找的解决方案已经讨论here。
TomasZ是对的,你应该使用TimerService的程序化计时器,以适应你想要在运行时动态更改计划的情况。