文档
Spring Framework 核心原理深入教程
第一章:IoC 容器深入
1.1 BeanFactory vs ApplicationContext
BeanFactory (接口)
└── ApplicationContext (接口)
├── ClassPathXmlApplicationContext
├── FileSystemXmlApplicationContext
├── AnnotationConfigApplicationContext
└── WebApplicationContext
| 特性 | BeanFactory | ApplicationContext |
|---|---|---|
| Bean 实例化 | 懒加载 | 预初始化(默认) |
| 国际化 | ❌ | ✅ MessageSource |
| 事件发布 | ❌ | ✅ ApplicationEvent |
| 资源加载 | ❌ | ✅ ResourceLoader |
| 使用场景 | 资源受限环境 | 生产环境推荐 |
1.2 Bean 生命周期
1. 实例化 (Instantiation)
2. 属性赋值 (Populate Properties)
3. BeanNameAware.setBeanName()
4. BeanFactoryAware.setBeanFactory()
5. ApplicationContextAware.setApplicationContext()
6. BeanPostProcessor.postProcessBeforeInitialization()
7. @PostConstruct / InitializingBean.afterPropertiesSet()
8. BeanPostProcessor.postProcessAfterInitialization()
9. Bean 就绪
10. @PreDestroy / DisposableBean.destroy() (容器关闭时)
1.3 作用域(Scope)
@Component
@Scope("singleton") // 默认,整个容器一个实例
public class SingletonBean { }
@Component
@Scope("prototype") // 每次获取创建新实例
public class PrototypeBean { }
@Component
@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class RequestScopedBean { } // Web 环境,每次 HTTP 请求
@Component
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class SessionScopedBean { } // Web 环境,每次 HTTP Session
第二章:依赖注入详解
2.1 三种注入方式对比
// 1. 构造器注入(推荐)—— 不可变、强制依赖
@Component
public class ConstructorInjection {
private final UserRepository repository;
public ConstructorInjection(UserRepository repository) {
this.repository = repository;
}
}
// 2. Setter 注入 —— 可选依赖
@Component
public class SetterInjection {
private Logger logger;
@Autowired(required = false)
public void setLogger(Logger logger) {
this.logger = logger;
}
}
// 3. 字段注入 —— 不推荐,难以测试
@Component
public class FieldInjection {
@Autowired
private UserRepository repository;
}
2.2 循环依赖
Spring 通过三级缓存解决单例 Setter 注入的循环依赖:
singletonObjects (一级缓存) → 完全初始化好的 Bean
earlySingletonObjects (二级缓存) → 早期引用(未完成属性填充)
singletonFactories (三级缓存) → Bean 工厂(可生成代理)
注意:构造器注入的循环依赖无法解决,会抛出 BeanCurrentlyInCreationException。
第三章:AOP 面向切面编程
3.1 核心概念
| 概念 | 说明 |
|---|---|
| Aspect | 切面,横切关注点的模块化 |
| Join Point | 连接点,方法执行点 |
| Advice | 通知,切面在连接点的行为 |
| Pointcut | 切入点,匹配连接点的表达式 |
| Weaving | 织入,将切面应用到目标对象 |
3.2 声明式事务实现原理
@Transactional
public void transfer(Long fromId, Long toId, BigDecimal amount) {
// Spring AOP 在方法执行前后:
// 1. 开启事务 (TransactionInterceptor)
// 2. 执行业务方法
// 3. 提交或回滚事务
}
Spring 使用 @Transactional → TransactionInterceptor → PlatformTransactionManager 链式处理。默认通过 JDK 动态代理或 CGLIB 代理实现。
3.3 自定义切面
@Aspect
@Component
public class LoggingAspect {
@Pointcut("execution(* com.example.service.*.*(..))")
public void serviceLayer() {}
@Before("serviceLayer()")
public void logBefore(JoinPoint joinPoint) {
System.out.println("调用: " + joinPoint.getSignature().getName());
}
@Around("serviceLayer()")
public Object measureTime(ProceedingJoinPoint pjp) throws Throwable {
long start = System.currentTimeMillis();
Object result = pjp.proceed();
long elapsed = System.currentTimeMillis() - start;
System.out.println("耗时: " + elapsed + "ms");
return result;
}
}
第四章:Spring MVC 请求处理流程
请求 → DispatcherServlet
→ HandlerMapping(找到 Handler + Interceptors)
→ HandlerAdapter(执行 Handler)
→ Handler(Controller)
→ 返回 ModelAndView
→ ViewResolver(解析视图)
→ View(渲染)
→ 响应
思考题
- 为什么构造器注入优于字段注入?
- Spring 三级缓存如何解决循环依赖,能否解决构造器注入的循环依赖?
- JDK 动态代理和 CGLIB 代理的区别,Spring 如何选择?
- 如何实现一个自定义 Spring Boot Starter?