创建监听器报错“一个或多个listeners启动失败”
问题:
今天写一个需求,即当项目启动时,取出数据库的商品类型,供全局使用,但是出现了
创建监听器报错“一个或多个listeners启动失败”。
解决:
错误示范:
我创建了两个IOC容器
@WebListener
public class ProductTypeListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
//这是又从新创建了一个IOC容器,不可以
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext_*.xml");
ProductTypeService productTypeService = (ProductTypeService) context.getBean("ProductTypeServiceImpl");
List<ProductType> typeList = productTypeService.getAll();
//放入全局应用作用域中,供新增页面,修改页面,前台的查询功能提供全部商品类别集合
servletContextEvent.getServletContext().setAttribute("typeList",typeList);
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
}
}
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext_*.xml</param-value>
</context-param>
正确示范:
@WebListener
public class ProductTypeListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
//拿到当前已经创建的IOC容器,而不是再创建一个
WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(servletContextEvent.getServletContext());
ProductTypeService productTypeService =(ProductTypeService) context.getBean("ProductTypeServiceImpl");
List<ProductType> typeList = productTypeService.getAll();
servletContextEvent.getServletContext().setAttribute("typeList",typeList);
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
}
}
原因:
- 重复加载 Spring 容器 :
ContextLoaderListener
已经通过<context-param>
配置加载了 Spring 容器,而你又手动创建了一个新的容器,导致资源浪费。 - Bean 不一致 :手动创建的容器与
ContextLoaderListener
加载的容器是独立的,可能导致 Bean 不一致(例如事务代理对象可能无法正常工作)。