spring容器概念,父子容器概念,默认容器组成,容器是怎么创建的,可以自定义容器,如何确立父子容器关联,存在同级容器吗
Spring 容器核心概念
Spring 容器是 Spring 框架的核心,负责对象的创建、管理、依赖注入(DI)和生命周期控制,是一个 “对象工厂”。它通过加载配置元数据(XML、注解、Java 配置类等),将开发者定义的 Bean 实例化并组织起来,供应用程序按需使用。容器的核心接口是
ApplicationContext(功能更丰富)和 BeanFactory(基础接口)。父子容器概念
父子容器是 Spring 中容器的层级关系设计,特点如下:
- 父容器:上层容器,可被多个子容器共享。
- 子容器:下层容器,可访问父容器中的 Bean,但父容器不能访问子容器的 Bean。
- 作用:实现功能隔离(如 Web 层与业务层分离),避免 Bean 名称冲突,同时允许子容器复用父容器的资源(如数据源、事务管理器)。
默认容器组成(以 Spring MVC 为例)
在典型的 Spring Web 应用中,默认存在父子容器结构:
- 父容器:通常由
ContextLoaderListener初始化,负责加载业务层、数据层 Bean(如 Service、Repository、数据源、事务管理器等)。 - 子容器:由
DispatcherServlet初始化,负责加载Web 层 Bean(如 Controller、HandlerMapping、ViewResolver 等)。 - 关系:子容器(Web 层)可访问父容器(业务层)的 Bean,但父容器不能访问子容器的 Bean。
容器的创建流程
Spring 容器的创建核心是加载配置并初始化 Bean,以
ApplicationContext 为例,大致流程:- 读取配置元数据:加载 XML 文件、注解类(@Configuration)或扫描指定包路径。
- 解析配置:将配置转换为 Spring 内部的数据结构(
BeanDefinition),包含 Bean 的类名、依赖、作用域等信息。 - 初始化容器:通过
BeanFactory实例化 Bean(非懒加载的单例 Bean 会在容器启动时创建),并完成依赖注入。 - 触发生命周期回调:调用 Bean 的初始化方法(如
@PostConstruct、InitializingBean接口)。
示例代码(手动创建容器):
// 基于XML配置创建容器
ApplicationContext parentContext = new ClassPathXmlApplicationContext("parent.xml");
// 基于注解扫描创建容器
ApplicationContext childContext = new AnnotationConfigApplicationContext("com.example.controller");
如何自定义容器
自定义容器通常通过扩展 Spring 的容器接口或自定义 BeanFactory实现,常见方式:
- 继承现有容器类:如扩展
AnnotationConfigApplicationContext,重写初始化逻辑。
public class CustomApplicationContext extends AnnotationConfigApplicationContext {
public CustomApplicationContext(Class<?>... annotatedClasses) {
super(annotatedClasses);
// 自定义初始化逻辑(如注册特定BeanPostProcessor)
}
}
- 实现
BeanFactory接口:适用于特殊场景,但需手动处理 Bean 的创建和依赖注入(较少用)。
确立父子容器关联
通过容器的
setParent() 方法建立关联,子容器会继承父容器的 Bean 定义和资源。示例:
// 创建父容器
ApplicationContext parent = new AnnotationConfigApplicationContext(ParentConfig.class);
// 创建子容器
AnnotationConfigApplicationContext child = new AnnotationConfigApplicationContext(ChildConfig.class);
// 关联父子容器
child.setParent(parent);
child.refresh(); // 刷新子容器使关联生效
存在同级容器吗?
存在。Spring 允许创建多个无层级关系的容器(同级容器),它们之间相互独立,无法访问彼此的 Bean。
示例:
// 两个同级容器,无父子关系
ApplicationContext container1 = new AnnotationConfigApplicationContext(Config1.class);
ApplicationContext container2 = new AnnotationConfigApplicationContext(Config2.class);
// container1 无法访问 container2 的Bean,反之亦然
同级容器适用于需要完全隔离的场景(如多模块独立运行),但实际开发中较少使用,更多依赖父子容器实现层级复用。
总结:Spring 容器通过层级关系(父子)实现资源隔离与共享,默认 Web 应用中由 ContextLoaderListener 和 DispatcherServlet 分别创建父子容器,开发者可通过
setParent()自定义关联,同时支持同级容器的独立存在。
浙公网安备 33010602011771号