Spring报错java.lang.IllegalStateException: Cannot set parent bean factory to self如何解决
异常根因
该异常触发的核心是Spring容器校验逻辑:为Bean工厂设置父容器时,如果父容器实例和当前容器是同一个对象,就会抛出java.lang.IllegalStateException: Cannot set parent bean factory to self错误。结合DispatcherServlet初始化的场景,常见触发场景有三类:
- 手动注册DispatcherServlet时,错误的将项目根Spring上下文直接赋值给Servlet的上下文属性,没有单独创建Servlet层的子上下文,导致上下文设置父容器时出现自引用
- 配置类重复添加
@EnableWebMvc注解,根上下文和Servlet上下文配置逻辑混淆,导致上下文实例被复用 - 自定义Web配置类错误覆盖了Spring默认的DispatcherServlet创建逻辑,比如继承
WebMvcConfigurationSupport时错误注入全局上下文,导致上下文引用关系混乱
排查解决步骤
- 检查DispatcherServlet注册逻辑:如果手动通过
ServletRegistrationBean注册DispatcherServlet,不要直接将注入的ApplicationContext设置为Servlet的上下文。正确写法参考:
// 错误写法 @Bean public ServletRegistrationBean dispatcherRegistration(ApplicationContext applicationContext) { DispatcherServlet dispatcherServlet = new DispatcherServlet(); dispatcherServlet.setApplicationContext(applicationContext); // 直接用根上下文会触发自引用 ServletRegistrationBean registration = new ServletRegistrationBean(dispatcherServlet, "/"); return registration; } // 正确写法 @Bean public ServletRegistrationBean dispatcherRegistration(ApplicationContext rootContext) { // 单独创建Servlet层的子上下文 AnnotationConfigWebApplicationContext servletContext = new AnnotationConfigWebApplicationContext(); servletContext.register(WebMvcConfig.class); servletContext.setParent(rootContext); // 显式设置根上下文为父容器 DispatcherServlet dispatcherServlet = new DispatcherServlet(servletContext); ServletRegistrationBean registration = new ServletRegistrationBean(dispatcherServlet, "/"); return registration; }
- 检查配置类注解:确认项目中只有一处
@EnableWebMvc配置,如果是Spring Boot项目优先删除手动添加的@EnableWebMvc注解,使用自动装配的MVC配置即可,避免上下文加载逻辑冲突。 - 排查自定义Bean冲突:检查是否存在手动定义的
DispatcherServlet类型Bean,删除多余的自定义Bean定义,优先使用Spring默认自动装配的DispatcherServlet。 - 快速定位验证:临时注释所有自定义的Web相关配置类,启动项目访问接口,如果异常消失,逐行恢复配置即可定位到出错的代码段。
内容的提问来源于stack exchange,提问作者katha
相关产品推荐
相关产品推荐

