因此,一旦Spring扫描并实例化了所有内容,我希望我的webapp能够运行一些代码来查找持久性中的某些项目,如果它们不存在,则使用属性文件中的值创建新项目,然后保留它们。 ......只是一些一般的初始化。
目前,我正在使用一个实现ApplicationListener的类。看起来这是处理这种情况的正常方法,但它似乎运行了两次。我必须添加一个私有布尔值并在onApplicationEvent方法中检查它以确保代码只运行一次:
private boolean initialized = false;
@Override
public void onApplicationEvent(ContextRefreshedEvent e) {
if (initialized){
return;
}
initializeStuff();
initialized = true;
}
这让我觉得我可能不是最好的方式。
有没有人对正确的处理方法有任何建议?
答案 0 :(得分:0)
我发现的最简单的方法(假设您已启用注释处理)当然是将初始化放在已使用@javax.annotation.PostConstruct
注释的方法中。只有在满足包含该方法的bean的所有依赖关系后才会调用该方法。
@PostConstruct
public void initializeStuff() {
// ...
}
最好分割你需要的任何初始化,以便bean负责定义自己的初始化,而不是在一个宏大的“初始化世界”方法中将知识集中在一起。
(您也可以通过XML配置启用此类功能,但我发现通过注释处理此类事情更简单,即使将XML配置用于其他所有内容,因为调用初始化程序是豆子不可分割的一部分。)
答案 1 :(得分:0)
它会执行两次,因为我认为,ContextLoaderListener
中的这个bean和DispatcherServlet
都有ContextRefreshedEvent
。从DispatcherServlet
气泡到父母的事件,因此ApplicationListener
执行两次。
您可能希望将此类移动到DispatcherServlet
,以便它执行一次(事件仅冒泡而不是关闭)。
而不是ApplicationListener
使ServletContextListener
成为ContextLoaderListener
之后加载WebApplicationUtils
,使用InitializingBean
从上下文中检索bean。这保证在应用程序启动期间执行一次。
或者创建一个实现@PostConstruct
的类或使用{{1}}注释bean的方法注入bean并在方法中加载数据。