假设我的主要课程是这样的:
public class TestTasker
{
private static GenericXmlApplicationContext context; // to be accessed by static main
public void runTask()
{
System.out.println("Current time is: " + new Date());
context.destroy();
initContext();
// if I do this instead..
// context.refresh();
// I'd get an exception:
// SEVERE: Invocation of method 'runTask' on target class [class spring.task.test.TestTasker] failed
// java.lang.IllegalStateException: GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once
// EDIT2: by using ClassPathXmlApplicationContext instead of generic context,
// I can call context.refresh() with no error.
}
private static initContext()
{
context = new GenericXmlApplicationContext("AppContext.xml");
}
public static void main(String[] args)
{
initContext();
}
}
和 AppContext.xml :
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:task="http://www.springframework.org/schema/task"
xmlns:util="http://www.springframework.org/schema/util" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd">
<!-- Task Scheduler -->
<task:annotation-driven />
<bean id="testTasker" class="spring.task.test.TestTasker" />
<util:properties id="applicationProps" location="application.properties" />
<context:property-placeholder
properties-ref="applicationProps" />
<task:scheduled-tasks>
<task:scheduled ref="testTasker" method="runTask"
cron="#{applicationProps['cron.expression']}" />
</task:scheduled-tasks>
</beans>
和 application.properties :
cron.expression=*/5 * * * * ?
如果我这样做,会有任何负面后果,例如内存泄漏(反复调用destroy和new context)吗?
有没有更好的解决方案?我只需要Spring自动/周期性地刷新 AppContext。
编辑:编辑了主类中的代码。调用context.refresh()
会产生此异常,
SEVERE: Invocation of method 'runTask' on target class [class spring.task.test.TestTasker] failed
java.lang.IllegalStateException: GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once
EDIT2 :通过使用ClassPathXmlApplicationContext
代替通用上下文,我可以调用context.refresh(),但没有错误。
答案 0 :(得分:1)
您可以使用context.refresh();
如果它失败了,它应该销毁已经创建的单例,以避免悬空资源。换句话说,在调用该方法之后,应该实例化全部或不实现单例。答案 1 :(得分:0)
GenericXmlApplicationContext.refresh()的问题是,它不支持多次刷新。你可以请分享你的更新代码。看起来它在初始化后不止一次被调用。
这是春季文档的内容
与为每次刷新创建新的内部BeanFactory实例的其他ApplicationContext实现相比,此上下文的内部BeanFactory从一开始就可用,以便能够在其上注册bean定义。 AbstractApplicationContext.refresh()只能被调用一次。
对于XML bean定义的典型情况,只需使用ClassPathXmlApplicationContext或FileSystemXmlApplicationContext,它们更容易设置 - 但不太灵活,因为您可以只使用XML bean定义的标准资源位置,而不是混合任意bean定义格式。 Web环境中的等效项是XmlWebApplicationContext。
对于应该以可刷新的方式读取特殊bean定义格式的自定义应用程序上下文实现,请考虑从AbstractRefreshableApplicationContext基类派生。