一、核心容器架构
1. 容器层级关系
- BeanFactory:根容器,提供基础的IoC功能,采用延迟加载策略
- ApplicationContext:子容器,继承BeanFactory,增加AOP、消息源、事件发布等企业级功能
- WebApplicationContext:专为Web应用设计的上下文,支持Request/Session作用域
2. 容器实现类
| 类型 | 加载来源 | 使用场景 |
|---|---|---|
ClassPathXmlApplicationContext |
类路径下的XML文件 | 传统XML配置项目 |
AnnotationConfigApplicationContext |
Java配置类 | 注解驱动项目 |
FileSystemXmlApplicationContext |
文件系统绝对路径 | 特殊文件位置需求 |
二、IOC与DI核心概念
IOC(Inversion of Control - 控制反转)
本质:将对象的创建、存储、管理权限从程序员转移给Spring容器
- 控制:创建对象的能力
- 反转:将创建权交给Spring,我们只需获取使用
DI(Dependency Injection - 依赖注入)
本质:在容器创建对象后,自动为其属性赋值(注入依赖)
- 作用:解耦对象间的依赖关系
- 方式:XML配置、注解、自动注入
个人理解口诀:IOC创建对象,DI给属性赋值
三、XML配置详解
1. Bean定义基础
xml
<bean id="userService" class="com.luo.service.impl.UserServiceImpl"
scope="singleton" lazy-init="false" autowire="byType">
<!-- 属性注入 -->
<property name="userDao" ref="userDao" />
<property name="name" value="小罗" />
</bean>
<bean id="userDao" class="com.luo.dao.impl.UserDaoImpl"/>
关键属性:
id:Bean唯一标识(默认首字母小写类名)class:类全路径scope:作用域(singleton/prototype)lazy-init:懒加载(默认false,启动时创建)autowire:自动注入模式
2. 依赖注入三种方式
- Setter注入 :通过
<property>标签调用setter方法 - 构造器注入 :通过
<constructor-arg>标签 - 自动注入 :
autowire="byType|byName|constructor"
四、Bean生命周期(重点背诵)
完整流程图
1. 解析配置 → BeanDefinition(元数据)
2. 实例化 → 构造函数创建对象
3. 属性注入 → DI(依赖注入)
4. 初始化 → 三种方式
├─ @PostConstruct
├─ InitializingBean.afterPropertiesSet()
└─ init-method指定
5. 使用 → getBean()返回实例
6. 销毁 → 三种方式
├─ @PreDestroy
├─ DisposableBean.destroy()
└─ destroy-method指定
单例 vs 多例
| 特性 | 单例(singleton) | 多例(prototype) |
|---|---|---|
| 创建时机 | 容器启动时创建(默认) | getBean()时创建 |
| 存储位置 | singletonObjects缓存集合 | 不缓存,每次都新建 |
| 内存占用 | 占用空间换时间效率 | 每次创建新实例 |
| 线程安全 | 需注意共享资源 | 天然线程安全 |
懒加载 :lazy-init="true" 使单例Bean在第一次获取时才创建
五、BeanDefinition vs singletonObjects
| 对象类型 | 存储内容 | 创建时机 | 存储位置 |
|---|---|---|---|
| BeanDefinition | Bean元数据(类名、作用域、属性、依赖等) | 容器启动解析配置时 | BeanFactory元数据区 |
| singletonObjects | 已实例化、注入、初始化的Bean对象 | 单例Bean实例化后 | 单例缓存池 |
关系:BeanDefinition是模板,singletonObjects是最终产品
六、扩展接口(高阶背诵)
1. BeanFactoryPostProcessor(Bean工厂后处理器)
执行时机 :所有Bean实例化之前,只执行一次
作用 :修改Bean定义、动态注册Bean、解析占位符
典型应用 :PropertySourcesPlaceholderConfigurer解析${}
2. BeanPostProcessor(Bean后处理器)
执行时机 :Bean实例化后、初始化前后各执行一次
作用 :AOP代理创建、依赖增强、性能监控
Spring AOP本质:通过BeanPostProcessor在初始化后创建代理对象
执行顺序:
实例化 → 属性注入 → postProcessBeforeInitialization →
初始化 → postProcessAfterInitialization → 就绪可用
七、FactoryBean机制(复杂对象创建)
使用场景
- 对象没有无参构造函数
- 创建代理对象
- 第三方框架整合
- 动态创建复杂对象
实现步骤
- 创建类实现
FactoryBean<T>接口 - 重写三个方法:
getObject():返回实际对象(会加入容器)getObjectType():返回对象类型isSingleton():是否单例(默认true)
- 配置Bean:
<bean id="user" class="UserFactoryBean"/>
注意 :容器中Bean的ID是getObject()返回的对象标识,而非FactoryBean本身
八、外部属性文件引入
xml
<!-- 1. 引入properties文件 -->
<context:property-placeholder location="classpath:jdbc.properties" />
<!-- 2. 使用占位符 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
作用:实现配置与代码分离,方便环境切换
九、Bean获取方式对比
java
// 1. 通过ID获取(不推荐,强依赖字符串)
Object bean = ctx.getBean("userService");
// 2. 通过ID+类型(特定场景)
UserService service = ctx.getBean("userService", UserService.class);
// 3. 通过类型(推荐,类型安全)
UserService service = ctx.getBean(UserService.class);
注意:同一类型多个Bean时,必须使用ID+类型方式
十、自动注入(Autowire)
| 模式 | 规则 | 适用场景 |
|---|---|---|
byType |
按类型匹配(默认) | 容器中该类型Bean唯一 |
byName |
按属性名匹配ID | 同类型多个Bean时 |
constructor |
按构造器参数类型 | 构造器注入时 |
注解等价物:
@Autowired=autowire="byType"@Resource(name="xxx")=autowire="byName"
十一、核心记忆口诀
容器篇
- 根容器:BeanFactory
- 子容器:ApplicationContext
- 加载方式:ClassPathXml、AnnotationConfig
IOC/DI篇
- IOC:控制反转,创建对象交给Spring
- DI:依赖注入,属性赋值自动化
- 配置:XML(property)、注解(@Value)
生命周期篇
- 四阶段:实例化 → 注入 → 初始化 → 使用
- 两后置:BeanPostProcessor前后拦截
- 一工厂:BeanFactoryPostProcessor前置修改
作用域篇
- 单例:启动创建,缓存共享(默认)
- 多例:获取创建,每次新建
- 懒加载:延迟单例创建时间
十二、面试高频问答
Q1: BeanFactory和ApplicationContext区别?
A: BeanFactory是基础容器,延迟加载;ApplicationContext是增强版,立即加载,支持更多企业级功能。
Q2: 单例Bean线程安全吗?
A: Spring不保证线程安全,需开发者自己保证。多例Bean天然线程安全。
Q3: @Autowired和@Resource区别?
A: @Autowired按类型注入(默认),@Resource按名称注入(默认)。
Q4: BeanPostProcessor作用?
A: 在Bean初始化前后执行,Spring AOP就是基于此实现的动态代理。
Q5: FactoryBean和BeanFactory区别?
A: BeanFactory是IoC容器工厂,FactoryBean是创建特殊Bean的工厂Bean。