核心原理深入教程

知识库
知识库文档
/tech-stacks/spring-framework/tutorial/核心原理深入教程.md

文档

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 使用 @TransactionalTransactionInterceptorPlatformTransactionManager 链式处理。默认通过 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(渲染)
       → 响应

思考题

  1. 为什么构造器注入优于字段注入?
  2. Spring 三级缓存如何解决循环依赖,能否解决构造器注入的循环依赖?
  3. JDK 动态代理和 CGLIB 代理的区别,Spring 如何选择?
  4. 如何实现一个自定义 Spring Boot Starter?

信息

路径
/tech-stacks/spring-framework/tutorial/核心原理深入教程.md
更新时间
2026/5/30