【问题标题】:Shutdown Equivalent of ApplicationContextInitializerApplicationContextInitializer 的关闭等效项
【发布时间】:2012-09-03 07:01:21
【问题描述】:
如何彻底关闭ApplicationContextInitializer 实现中使用的资源?
我创建了一个 ApplicationContextInitializer 实现,它使用 Curator 项目连接到 Zookeeper 并获取一个属性文件。然后它创建一个 Properties 实例,一个 PropertiesPropertySource 并将其添加到上下文中。
当应用程序关闭时,我希望能够在作为我的初始化程序成员的CuratorFramework 实例上调用close()。如何做到最好?
我是否也可以将CuratorFramework 实例传递到上下文中,这样我就可以将它用作bean?
【问题讨论】:
标签:
java
spring
apache-zookeeper
apache-curator
【解决方案1】:
在您的ApplicationContextInitializer 中,您可以添加一个ApplicationListener<ContextClosedEvent>:
class MyContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
applicationContext.addApplicationListener(new ApplicationListener<ContextClosedEvent>() {
@Override
public void onApplicationEvent(ContextClosedEvent event) {
/* Cleanup code */
}
});
}
}
【解决方案2】:
我会创建一个获取 spring 事件的 bean,并使用它来关闭 curator,
public class CuratorDisposer implements DisposableBean {
private CuratorFramework delegate; //set through spring somehow
public void destroy() {
delegate.close();
}
}
【解决方案3】:
当应用程序关闭时,我希望能够调用 close()
在作为我的初始化程序成员的 CuratorFramework 实例上。
如何做到最好?
您可以让您的初始化程序类实现ApplicationListener,然后将自己注册为上下文中的侦听器。然后,当上下文关闭时,您将收到 ContextClosedEvent。
我是否也可以将CuratorFramework 实例传递到上下文中,这样我就可以将它用作一个bean?
您可以在初始化程序中执行类似的操作(未测试):
RootBeanDefinition cfDef = new RootBeanDefinition(MethodInvokingFactoryBean.class);
cfDef.getPropertyValues().add("targetClass", MyInitializer.class);
cfDef.getPropertyValues().add("targetObject", this);
cfDef.getPropertyValues().add("targetMethod", "getCuratorFramework");
((BeanDefinitionRegistry)ctx).registerBeanDefinition("curatorFramework", cfDef);
并将getCuratorFramework() 方法添加到您的初始化程序类,返回您在初始化时创建的CuratorFramework。