我想在 contextDestroyed 中获取 bean,所以我有这段代码。
public class MyContextListener implements ApplicationContextAware, ServletContextListener {
private final Logger logger = LogManager.getLogger(getClass());
private ApplicationContext appContext;
@Override
public void contextInitialized(ServletContextEvent event) {
logger.warn("Start");
}
@Override
public void contextDestroyed(ServletContextEvent event) {
logger.warn("End" + appContext);
appContext.getBean("myBean")
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.appContext = applicationContext;
}
}
问题是它记录了null
。但是当我将其更改为
private static ApplicationContext appContext;
然后我就可以看到我的appContext。为什么 ?获得bean的正确选择是什么
最佳答案
您有 2 个 MyContextListener
实例。一种由 Spring 配置,另一种由 Web 容器配置。
Spring 配置的将具有 ApplicationContextAware
回调并设置 appContext
属性,但您的 servlet 容器不知道它,因此不会参与在生命周期回调中。
第二个实例是 servlet 容器中的实例,但是由于它不是 spring 管理的实例,因此它不会收到 ApplicationContextAware
的回调,因此 appContext
code> 将是 null
。
使其静态
可以“解决”它,因为它现在是一个类变量而不是实例变量。现在所有实例都共享该变量。
最好删除 ApplicationContextAware
并在监听器中使用 WebApplicationContextUtils.getRequiredWebApplicationContext
方法。
public class MyContextListener extends BaseTask implements ServletContextListener {
private final Logger logger = LogManager.getLogger(getClass());
@Override
public void contextInitialized(ServletContextEvent event) {
logger.warn("Start");
}
@Override
public void contextDestroyed(ServletContextEvent event) {
logger.warn("End" + appContext);
WebApplicationContextUtils.getRequiredWebApplicationContext(event.getServletContext()).getBean("myBean");
}
}
现在您只需要 servlet 容器的实例(web.xml 或其他配置方式),并且可以删除 spring 托管实例。
关于java - 如何从 contextDestroyed 中的 ServletContextListener 获取 bean,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34608584/