spring boot父子容器依赖注入隔离的核心是通过容器层级与扫描范围控制实现bean的分层注册与查找。父容器(root context)加载非web组件,子容器(servlet context)仅加载web组件,通过exclude-filter和include-filter精确控制扫描范围,子容器可访问父容器bean但遵循就近原则,同名bean在子容器中优先使用本地定义版本。

Spring Boot 中父子容器的依赖注入隔离,核心在于利用容器层级关系和扫描范围控制,让 Bean 只在指定容器中注册、查找和注入,从而避免跨模块干扰或重复加载。
父容器不扫 Web 层,子容器只扫 Web 层
这是最常用也最有效的隔离方式。父容器(Root Context)负责加载业务服务、数据源、事务管理器等非 Web 组件;子容器(Servlet Context)只负责控制器、拦截器、视图解析器等 Web 相关 Bean。
- 父容器配置中显式排除 @Controller 和 @RestController 注解类:
- 子容器配置中关闭默认扫描,仅包含 Web 相关注解:
子容器无法反向注入父容器未暴露的 Bean
子容器能访问父容器中的 Bean,但前提是父容器已将该 Bean 注册且未被子容器同名覆盖。若子容器自己定义了同名 Bean(比如两个模块都声明了 UserService),则子容器内注入的会是它自己的版本,父容器的不会“透过来”。
- 注入时按“就近原则”:先查当前容器,找不到再向上委托到父容器
- 父容器中的
@Service或@RepositoryBean 不会被子容器自动覆盖,但子容器若用相同@Bean方法或@Component声明同名类,就会屏蔽父容器版本 - 若需强制使用父容器 Bean,可在子容器中通过
@Autowired(required = false)配合@Qualifier("parentUserService")显式指定
自定义子容器实现模块级隔离
对复杂系统,可为每个业务模块(如订单、用户、支付)创建独立子容器,通过编程方式控制扫描路径与生命周期。
- 继承
AnnotationConfigServletWebServerFactory或手动构建GenericWebApplicationContext作为子容器 - 用
BeanPostProcessor拦截特定注解(如@Module("order")),动态注册对应包路径的子容器 - 子容器启动时设置父容器为 Root Context,并限定
setParent(),确保依赖查找链完整 - 模块间通信统一走接口抽象(如
OrderServiceApi),由父容器托管实现类,子容器只注入接口
注意嵌入式容器带来的隐式父子结构
Spring Boot 默认使用嵌入式 Tomcat,其内部会自动创建 Servlet Context 作为子容器,Root Context 是父容器。这个结构不可禁用,但可干预:
- 所有
@Configuration类默认在 Root Context 中生效 - 若在
@SpringBootApplication同包下放@Controller,它会被 Root Context 扫到——除非你显式用@ComponentScan(excludeFilters = ...)排除 -
DispatcherServlet初始化时会创建自己的WebApplicationContext,它自动以 Root Context 为父,无需手动 setParent











