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 { }
@Component
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class SessionScopedBean { }
第二章:依赖注入详解
2.1 三种注入方式对比
@Component
public class ConstructorInjection {
private final UserRepository repository;
public ConstructorInjection(UserRepository repository) {
this.repository = repository;
}
}
@Component
public class SetterInjection {
private Logger logger;
@Autowired(required = false)
public void setLogger(Logger logger) {
this.logger = logger;
}
}
@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 使用 @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?