Spring 源码之旅:IoC 容器、AOP 实现、事务传播机制

写在前面

作为一个 Java 后端开发,你每天都在用 Spring,但你真的理解它吗?

  • 为什么在类上加个 @Component 注解,Spring 就能自动创建对象?

  • 为什么在方法上加个 @Transactional,方法执行失败就会自动回滚?

  • 为什么 @Autowired 能自动注入依赖,背后到底发生了什么?

今天,我们深入 Spring 源码,揭开这三大核心机制的神秘面纱:

  1. IoC 容器: Bean 的生命周期、循环依赖、三级缓存

  2. AOP 实现: 动态代理、切面织入、拦截器链

  3. 事务传播: 七种传播行为、底层实现原理

准备好了吗?让我们开始这场源码探险!


一、IoC 容器:Spring 的"心脏"

1.1 核心问题:Spring 如何管理对象?

传统方式:手动 new 对象

public class OrderService {
    private UserService userService = new UserService();  // 强耦合
    private ProductService productService = new ProductService();
}

问题:

  • 对象创建逻辑散落各处

  • 难以替换实现(比如测试时替换为 Mock)

  • 对象生命周期难以管理

Spring 的解决方案:IoC(控制反转)

@Service
public class OrderService {
    @Autowired
    private UserService userService;  // Spring 自动注入
    @Autowired
    private ProductService productService;
}

核心思想: 把对象的创建和依赖关系的管理交给 Spring 容器,你只管用!


1.2 Spring IoC 容器的核心接口

Spring IoC 容器的设计是典型的分层架构:

BeanFactory (最顶层接口)
    ↓
ApplicationContext (扩展接口,增加了更多企业级特性)
    ↓
AnnotationConfigApplicationContext (基于注解的实现)
ClassPathXmlApplicationContext (基于 XML 的实现)

核心接口:BeanFactory

public interface BeanFactory {
    Object getBean(String name);  // 根据名称获取 Bean
    <T> T getBean(Class<T> requiredType);  // 根据类型获取 Bean
    boolean containsBean(String name);  // 是否包含某个 Bean
}

扩展接口:ApplicationContext

public interface ApplicationContext extends BeanFactory {
    // 继承了 BeanFactory 的所有能力,并新增:
    // 1. 事件发布机制
    // 2. 国际化支持
    // 3. 资源加载
    // 4. 环境抽象
}


1.3 Bean 的完整生命周期(源码级解析)

这是面试高频问题!完整的 Bean 生命周期有 11 个步骤:

1. 实例化 Bean (createBeanInstance)
   ↓
2. 设置属性值 (populateBean)
   ↓
3. 调用 BeanNameAware.setBeanName()
   ↓
4. 调用 BeanFactoryAware.setBeanFactory()
   ↓
5. 调用 ApplicationContextAware.setApplicationContext()
   ↓
6. 调用 BeanPostProcessor.postProcessBeforeInitialization() (前置处理)
   ↓
7. 调用 @PostConstruct 注解的方法
   ↓
8. 调用 InitializingBean.afterPropertiesSet()
   ↓
9. 调用 init-method 指定的方法
   ↓
10. 调用 BeanPostProcessor.postProcessAfterInitialization() (后置处理)
    ↓
11. Bean 可以使用了
    ↓
12. 容器关闭时,调用 @PreDestroy、DisposableBean.destroy()、destroy-method

核心源码:AbstractAutowireCapableBeanFactory.doCreateBean()

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, Object[] args) {
    // 1. 实例化 Bean
    BeanWrapper instanceWrapper = createBeanInstance(beanName, mbd, args);
    Object bean = instanceWrapper.getWrappedInstance();
    
    // 2. 属性注入
    populateBean(beanName, mbd, instanceWrapper);
    
    // 3. 初始化 Bean(执行各种 Aware 接口、@PostConstruct、init-method)
    Object exposedObject = initializeBean(beanName, bean, mbd);
    
    return exposedObject;
}


1.4 循环依赖问题:三级缓存的精妙设计

场景重现:

@Service
public class A {
    @Autowired
    private B b;  // A 依赖 B
}

@Service
public class B {
    @Autowired
    private A a;  // B 依赖 A
}

问题: A 需要 B,B 需要 A,谁先创建?这就是经典的循环依赖!

Spring 的解决方案:三级缓存

public class DefaultSingletonBeanRegistry {
    // 一级缓存:成品 Bean(完全初始化完成)
    private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
    
    // 二级缓存:半成品 Bean(实例化完成,但属性未注入)
    private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
    
    // 三级缓存:Bean 工厂(用于生成代理对象)
    private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
}

解决流程(以 A、B 循环依赖为例):

1. 创建 A:
   - 实例化 A(此时 A 是半成品,属性 b 为 null)
   - 将 A 的工厂放入三级缓存
   - 开始注入属性 b

2. 创建 B:
   - 实例化 B(此时 B 是半成品,属性 a 为 null)
   - 将 B 的工厂放入三级缓存
   - 开始注入属性 a

3. 注入 A 到 B:
   - 从三级缓存中获取 A 的工厂
   - 调用工厂创建 A 的早期引用(可能是代理对象)
   - 将早期引用放入二级缓存
   - 注入到 B 的属性 a

4. B 创建完成:
   - 将 B 从三级缓存移除
   - 将 B 放入一级缓存

5. 继续创建 A:
   - 注入 B 到 A 的属性 b(B 已在一级缓存中)
   - A 创建完成,移入一级缓存

为什么需要三级缓存?

  • 一级缓存不够? 无法解决循环依赖(A 需要 B,但 A 还没创建完)

  • 二级缓存不够? 无法处理 AOP 代理(需要提前暴露代理对象)

  • 三级缓存: 延迟创建代理对象,只有在循环依赖时才提前创建代理

核心源码:

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    // 1. 先从一级缓存获取(成品)
    Object singletonObject = this.singletonObjects.get(beanName);
    
    if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
        // 2. 从二级缓存获取(半成品)
        singletonObject = this.earlySingletonObjects.get(beanName);
        
        if (singletonObject == null && allowEarlyReference) {
            synchronized (this.singletonObjects) {
                // 3. 从三级缓存获取工厂,创建早期引用
                ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                if (singletonFactory != null) {
                    singletonObject = singletonFactory.getObject();  // 可能返回代理对象
                    // 放入二级缓存
                    this.earlySingletonObjects.put(beanName, singletonObject);
                    // 从三级缓存移除
                    this.singletonFactories.remove(beanName);
                }
            }
        }
    }
    return singletonObject;
}


1.5 @Autowired 注入原理

核心问题:Spring 如何知道哪些字段需要注入?

答案: AutowiredAnnotationBeanPostProcessor(后置处理器)

执行流程:

1. 扫描类,找到所有 @Autowired 注解的字段/方法
   ↓
2. 将注入点信息缓存(InjectionMetadata)
   ↓
3. 在 Bean 初始化时,调用 postProcessProperties()
   ↓
4. 根据类型从容器中查找 Bean
   ↓
5. 通过反射设置字段值

简化源码:

public class AutowiredAnnotationBeanPostProcessor {
    
    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
        // 1. 获取需要注入的元数据
        InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
        
        // 2. 执行注入
        metadata.inject(bean, beanName, pvs);
        return pvs;
    }
    
    private void inject(Object target, String beanName, PropertyValues pvs) {
        Field field = ...; // 获取字段
        
        // 3. 从容器中解析依赖
        Object value = resolveFieldValue(field, target, beanName);
        
        // 4. 反射设置值
        ReflectionUtils.makeAccessible(field);
        field.set(target, value);
    }
}


二、AOP 实现:方法拦截的魔法

2.1 AOP 的核心概念

业务场景:

public class OrderService {
    public void createOrder() {
        // 1. 记录日志
        // 2. 开启事务
        // 3. 业务逻辑
        // 4. 提交事务
        // 5. 记录日志
    }
}

问题: 日志、事务这些横切关注点散落在各个方法中,代码重复、难以维护。

AOP 的解决方案:

@Aspect
@Component
public class LogAspect {
    
    @Around("execution(* com.example.service.*.*(..))")
    public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("方法执行前");
        Object result = joinPoint.proceed();  // 执行目标方法
        System.out.println("方法执行后");
        return result;
    }
}

五大核心概念:

  • Aspect(切面): 横切关注点的模块化(如日志切面、事务切面)

  • Join Point(连接点): 程序执行的某个点(如方法调用)

  • Pointcut(切点): 匹配连接点的表达式(决定在哪些方法上应用)

  • Advice(通知): 在切点执行的代码(Before、After、Around 等)

  • Weaving(织入): 将切面应用到目标对象的过程


2.2 动态代理:AOP 的底层实现

Spring AOP 底层有两种代理方式:

代理方式

使用场景

优缺点

JDK 动态代理

目标类实现了接口

只能代理接口方法

CGLIB 代理

目标类没有接口

通过子类继承,不能代理 final 方法

JDK 动态代理示例:

public class JdkProxyFactory implements InvocationHandler {
    private Object target;
    
    public Object getProxy(Object target) {
        this.target = target;
        return Proxy.newProxyInstance(
            target.getClass().getClassLoader(),
            target.getClass().getInterfaces(),
            this
        );
    }
    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("方法执行前");
        Object result = method.invoke(target, args);  // 调用真实方法
        System.out.println("方法执行后");
        return result;
    }
}

CGLIB 代理示例:

public class CglibProxyFactory implements MethodInterceptor {
    
    public Object getProxy(Class<?> clazz) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(clazz);  // 设置父类
        enhancer.setCallback(this);
        return enhancer.create();
    }
    
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) {
        System.out.println("方法执行前");
        Object result = proxy.invokeSuper(obj, args);  // 调用父类方法
        System.out.println("方法执行后");
        return result;
    }
}


2.3 Spring AOP 创建代理的时机

核心问题:什么时候创建代理对象?

答案: 在 Bean 初始化的后置处理阶段!

还记得 Bean 生命周期的第 10 步吗?BeanPostProcessor.postProcessAfterInitialization()

核心类:AbstractAutoProxyCreator

public abstract class AbstractAutoProxyCreator implements BeanPostProcessor {
    
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        // 1. 判断是否需要代理(是否匹配切点表达式)
        if (shouldProxy(bean, beanName)) {
            // 2. 获取所有匹配的 Advisor(包含 Pointcut + Advice)
            Object[] advisors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName);
            
            // 3. 创建代理对象
            return createProxy(bean.getClass(), beanName, advisors, bean);
        }
        
        return bean;  // 不需要代理,返回原对象
    }
    
    protected Object createProxy(Class<?> beanClass, String beanName, Object[] advisors, Object target) {
        ProxyFactory proxyFactory = new ProxyFactory();
        proxyFactory.setTarget(target);
        proxyFactory.addAdvisors(advisors);
        
        // 决定使用 JDK 还是 CGLIB
        if (beanClass.isInterface() || hasInterface(beanClass)) {
            return proxyFactory.getJdkProxy();  // JDK 动态代理
        } else {
            return proxyFactory.getCglibProxy();  // CGLIB 代理
        }
    }
}


2.4 拦截器链的执行流程

场景: 一个方法上有多个切面(事务、日志、权限校验...)

@Transactional
@Log
@CheckPermission
public void createOrder() {
    // 业务逻辑
}

执行顺序: Spring 会将所有 Advice 组成一个拦截器链(责任链模式)

1. 事务切面 - Before
   ↓
2. 日志切面 - Before
   ↓
3. 权限切面 - Before
   ↓
4. 执行目标方法
   ↓
5. 权限切面 - After
   ↓
6. 日志切面 - After
   ↓
7. 事务切面 - After

核心源码:ReflectiveMethodInvocation

public class ReflectiveMethodInvocation implements MethodInvocation {
    private final List<Object> interceptorsAndDynamicMethodMatchers;  // 拦截器链
    private int currentInterceptorIndex = -1;  // 当前执行到第几个
    
    @Override
    public Object proceed() throws Throwable {
        // 所有拦截器执行完,调用目标方法
        if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
            return invokeJoinpoint();  // 反射调用目标方法
        }
        
        // 获取下一个拦截器
        Object interceptor = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
        
        // 执行拦截器(拦截器内部会再次调用 proceed(),形成递归)
        return ((MethodInterceptor) interceptor).invoke(this);
    }
}

执行原理(递归调用):

// 第一个拦截器
public Object invoke(MethodInvocation invocation) {
    doBefore();  // 前置通知
    Object result = invocation.proceed();  // 递归调用下一个拦截器
    doAfter();   // 后置通知
    return result;
}


三、事务传播机制:嵌套事务的艺术

3.1 核心问题:事务方法互相调用怎么办?

场景 1:转账 + 记录日志

@Transactional
public void transfer(String from, String to, BigDecimal amount) {
    deductBalance(from, amount);  // 扣款
    addBalance(to, amount);       // 加款
    logTransfer(from, to, amount); // 记录日志(这个失败了不应该回滚转账!)
}

场景 2:批量插入

@Transactional
public void batchInsert(List<User> users) {
    for (User user : users) {
        saveUser(user);  // 一个失败,其他还要不要保存?
    }
}

问题核心: 内部方法的事务该如何处理?


3.2 七种事务传播行为

传播行为

说明

使用场景

REQUIRED (默认)

如果有事务,加入;没有则新建

99% 的场景

REQUIRES_NEW

总是新建事务,挂起当前事务

日志记录(失败不影响主业务)

NESTED

嵌套事务,外部回滚,内部也回滚;内部回滚,外部可捕获异常决定

批量操作(部分失败)

SUPPORTS

有事务就用,没有就不用

查询方法

NOT_SUPPORTED

以非事务方式执行,挂起当前事务

不需要事务的操作

MANDATORY

必须在事务中执行,否则抛异常

强制事务约束

NEVER

不能在事务中执行,否则抛异常

禁止事务的操作


3.3 实战案例:REQUIRED vs REQUIRES_NEW

REQUIRED(默认):

@Service
public class OrderService {
    @Autowired
    private LogService logService;
    
    @Transactional(propagation = Propagation.REQUIRED)
    public void createOrder() {
        // 插入订单
        orderRepository.save(order);
        
        // 记录日志(加入当前事务)
        logService.log("订单创建");  // 如果这里抛异常,订单也会回滚!
    }
}

@Service
public class LogService {
    @Transactional(propagation = Propagation.REQUIRED)
    public void log(String message) {
        logRepository.save(message);
        throw new RuntimeException("日志失败");  // 导致整个事务回滚
    }
}

REQUIRES_NEW(日志不影响主业务):

@Service
public class LogService {
    @Transactional(propagation = Propagation.REQUIRES_NEW)  // 新建独立事务
    public void log(String message) {
        logRepository.save(message);
        throw new RuntimeException("日志失败");  // 只回滚日志,不影响订单
    }
}

@Service
public class OrderService {
    @Transactional
    public void createOrder() {
        orderRepository.save(order);
        
        try {
            logService.log("订单创建");  // 独立事务
        } catch (Exception e) {
            // 捕获异常,订单事务不受影响
        }
    }
}


3.4 NESTED:嵌套事务的精妙设计

场景:批量导入用户,部分失败不影响其他

@Service
public class UserService {
    
    @Transactional
    public void batchImport(List<User> users) {
        int successCount = 0;
        
        for (User user : users) {
            try {
                saveUser(user);  // 嵌套事务
                successCount++;
            } catch (Exception e) {
                log.error("用户 {} 导入失败", user.getName(), e);
                // 继续处理下一个用户
            }
        }
        
        log.info("成功导入 {} 个用户", successCount);
    }
    
    @Transactional(propagation = Propagation.NESTED)
    public void saveUser(User user) {
        // 验证用户
        if (user.getAge() < 0) {
            throw new IllegalArgumentException("年龄不能为负数");
        }
        
        // 保存用户
        userRepository.save(user);
    }
}

NESTED 的特点:

  • 内部事务回滚不影响外部(通过 Savepoint 实现)

  • 外部事务回滚会影响内部

  • 底层原理: 数据库的 Savepoint 机制

-- 外部事务开始
BEGIN;

-- 设置保存点
SAVEPOINT sp1;

-- 内部事务操作
INSERT INTO user ...;

-- 内部事务失败,回滚到保存点
ROLLBACK TO sp1;

-- 继续外部事务
INSERT INTO user ...;

-- 外部事务提交
COMMIT;


3.5 事务传播的底层实现

核心类:TransactionInterceptor

public class TransactionInterceptor extends TransactionAspectSupport {
    
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        // 1. 获取目标类和方法
        Class<?> targetClass = invocation.getThis().getClass();
        Method method = invocation.getMethod();
        
        // 2. 执行事务逻辑
        return invokeWithinTransaction(method, targetClass, invocation::proceed);
    }
    
    protected Object invokeWithinTransaction(Method method, Class<?> targetClass, InvocationCallback invocation) {
        // 3. 获取事务属性(传播行为、隔离级别等)
        TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
        
        // 4. 获取事务管理器
        PlatformTransactionManager tm = determineTransactionManager(txAttr);
        
        // 5. 根据传播行为决定如何处理事务
        TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
        
        Object retVal;
        try {
            // 6. 执行目标方法
            retVal = invocation.proceedWithInvocation();
        } catch (Throwable ex) {
            // 7. 异常时回滚
            completeTransactionAfterThrowing(txInfo, ex);
            throw ex;
        } finally {
            cleanupTransactionInfo(txInfo);
        }
        
        // 8. 成功时提交
        commitTransactionAfterReturning(txInfo);
        return retVal;
    }
}

核心方法:handleExistingTransaction(处理已存在的事务)

private TransactionStatus handleExistingTransaction(TransactionAttribute definition, Object transaction) {
    
    // REQUIRES_NEW:挂起当前事务,创建新事务
    if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {
        SuspendedResourcesHolder suspendedResources = suspend(transaction);  // 挂起
        TransactionStatus status = startTransaction(definition, transaction);  // 新建
        return status;
    }
    
    // NESTED:创建保存点
    if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
        Object savepoint = transaction.createSavepoint();  // 设置保存点
        return prepareTransactionStatus(definition, transaction, false, savepoint);
    }
    
    // REQUIRED:加入当前事务
    return prepareTransactionStatus(definition, transaction, false, null);
}


四、Spring 源码调试技巧

4.1 如何调试 Bean 创建过程?

在这些方法上打断点:

1. AbstractApplicationContext.refresh()  // 容器启动入口
2. AbstractAutowireCapableBeanFactory.doCreateBean()  // Bean 创建
3. AbstractAutowireCapableBeanFactory.populateBean()  // 属性注入
4. AbstractAutowireCapableBeanFactory.initializeBean()  // 初始化

4.2 如何调试 AOP 代理创建?

1. AbstractAutoProxyCreator.postProcessAfterInitialization()  // 代理创建入口
2. ProxyFactory.getProxy()  // 代理生成
3. ReflectiveMethodInvocation.proceed()  // 拦截器链执行

4.3 如何调试事务传播?

1. TransactionInterceptor.invoke()  // 事务拦截入口
2. TransactionAspectSupport.invokeWithinTransaction()  // 事务处理
3. AbstractPlatformTransactionManager.getTransaction()  // 获取/创建事务
4. DataSourceTransactionManager.doBegin()  // 开启事务


五、常见面试题与最佳实践

5.1 高频面试题

Q1:Spring Bean 的作用域有哪些?

  • singleton(默认): 单例,整个容器只有一个实例

  • prototype: 原型,每次获取都创建新实例

  • request: 每个 HTTP 请求一个实例(Web 环境)

  • session: 每个 HTTP Session 一个实例

  • application: 整个 ServletContext 一个实例

Q2:Spring 如何解决循环依赖?

  • 通过三级缓存

  • 只能解决单例 setter 注入的循环依赖

  • 不能解决构造器注入的循环依赖(死循环)

  • 不能解决 prototype 作用域的循环依赖

Q3:@Transactional 失效的场景?

  1. 方法不是 public

  2. 同类内部调用(this.method())

  3. 异常被捕获没有抛出

  4. 抛出的是 checked 异常(需配置 rollbackFor)

  5. 数据库不支持事务(如 MyISAM)


5.2 最佳实践

1. 避免循环依赖

// ❌ 不推荐:构造器注入导致循环依赖
@Service
public class A {
    public A(B b) {}
}

// ✅ 推荐:setter 注入或 @Lazy
@Service
public class A {
    @Autowired
    @Lazy
    private B b;
}

2. 事务方法不要过长

// ❌ 不推荐:事务范围过大
@Transactional
public void longRunningTask()
{ 
  // 大量业务逻辑 
  complexCalculation(); // 耗时 5 秒 
  callExternalApi(); // 耗时 3 秒 
  sendEmail(); // 耗时 2 秒 
  saveToDatabase(); // 真正需要事务的操作 
}

// ✅ 推荐:只在必要的地方加事务 
public void longRunningTask() { 
   complexCalculation();
   callExternalApi(); 
   sendEmail();
  // 只在数据库操作时开启事务
   transactionalService.saveToDatabase();
}

@Service 
class TransactionalService { 
  @Transactional 
  public void saveToDatabase() 
  { 
    // 数据库操作 
  } 
}

3. 合理使用事务传播行为

// ❌ 错误:日志失败导致业务回滚
@Transactional
public void createOrder() {
    saveOrder();
    logService.log();  // 日志失败,订单也回滚了
}

// ✅ 正确:日志使用独立事务
@Transactional
public void createOrder() {
    saveOrder();
    try {
        logService.logWithNewTransaction();  // REQUIRES_NEW
    } catch (Exception e) {
        // 日志失败不影响订单
    }
}

4. 注意同类调用事务失效

@Service
public class OrderService {
    
    // ❌ 错误:内部调用,事务不生效
    public void createOrder() {
        this.saveOrder();  // 直接调用,没有走代理
    }
    
    @Transactional
    public void saveOrder() {
        // 事务不生效!
    }
    
    // ✅ 解决方案 1:注入自己
    @Autowired
    private OrderService self;
    
    public void createOrderV2() {
        self.saveOrder();  // 通过代理调用
    }
    
    // ✅ 解决方案 2:使用 AopContext
    public void createOrderV3() {
        ((OrderService) AopContext.currentProxy()).saveOrder();
    }
    
    // ✅ 解决方案 3:拆分到不同类
    @Autowired
    private OrderRepository orderRepository;
    
    public void createOrderV4() {
        orderRepository.saveOrder();  // 调用其他 Bean
    }
}


六、进阶话题:从源码中学习设计模式

6.1 Spring 中的设计模式

1. 工厂模式(Factory)

// BeanFactory:创建 Bean 的工厂
public interface BeanFactory {
    Object getBean(String name);
}

// 简化版实现
public class SimpleBeanFactory implements BeanFactory {
    private Map<String, Object> beanMap = new ConcurrentHashMap<>();
    
    @Override
    public Object getBean(String name) {
        if (!beanMap.containsKey(name)) {
            beanMap.put(name, createBean(name));
        }
        return beanMap.get(name);
    }
}

2. 单例模式(Singleton)

// DefaultSingletonBeanRegistry:单例注册表
public class DefaultSingletonBeanRegistry {
    private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>();
    
    public void registerSingleton(String beanName, Object singletonObject) {
        synchronized (this.singletonObjects) {
            this.singletonObjects.put(beanName, singletonObject);
        }
    }
    
    public Object getSingleton(String beanName) {
        return this.singletonObjects.get(beanName);
    }
}

3. 代理模式(Proxy)

// AOP 的核心:JDK 动态代理 + CGLIB 代理
public class ProxyFactory {
    public Object getProxy() {
        if (hasInterface()) {
            return createJdkProxy();  // 代理接口
        } else {
            return createCglibProxy();  // 代理类
        }
    }
}

4. 模板方法模式(Template Method)

// AbstractApplicationContext:定义容器刷新的模板流程
public abstract class AbstractApplicationContext {
    
    public void refresh() {
        // 1. 准备刷新
        prepareRefresh();
        
        // 2. 刷新 BeanFactory
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
        
        // 3. 准备 BeanFactory
        prepareBeanFactory(beanFactory);
        
        // 4. 后置处理 BeanFactory(子类扩展点)
        postProcessBeanFactory(beanFactory);
        
        // 5. 执行 BeanFactoryPostProcessor
        invokeBeanFactoryPostProcessors(beanFactory);
        
        // 6. 注册 BeanPostProcessor
        registerBeanPostProcessors(beanFactory);
        
        // 7. 初始化消息源
        initMessageSource();
        
        // 8. 初始化事件广播器
        initApplicationEventMulticaster();
        
        // 9. 刷新(子类扩展点)
        onRefresh();
        
        // 10. 注册监听器
        registerListeners();
        
        // 11. 实例化所有单例 Bean
        finishBeanFactoryInitialization(beanFactory);
        
        // 12. 完成刷新
        finishRefresh();
    }
    
    // 子类可以重写的扩展点
    protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {}
    protected void onRefresh() {}
}

5. 观察者模式(Observer)

// Spring 事件机制
public interface ApplicationListener<E extends ApplicationEvent> {
    void onApplicationEvent(E event);
}

// 发布事件
@Service
public class OrderService {
    @Autowired
    private ApplicationEventPublisher publisher;
    
    public void createOrder() {
        // 业务逻辑
        Order order = saveOrder();
        
        // 发布事件
        publisher.publishEvent(new OrderCreatedEvent(order));
    }
}

// 监听事件
@Component
public class OrderListener implements ApplicationListener<OrderCreatedEvent> {
    @Override
    public void onApplicationEvent(OrderCreatedEvent event) {
        // 发送通知、更新库存等
        System.out.println("订单创建成功:" + event.getOrder().getId());
    }
}

6. 责任链模式(Chain of Responsibility)

// AOP 拦截器链
public class ReflectiveMethodInvocation {
    private List<MethodInterceptor> interceptors;
    private int currentIndex = -1;
    
    public Object proceed() {
        // 所有拦截器执行完
        if (currentIndex == interceptors.size() - 1) {
            return invokeTargetMethod();
        }
        
        // 执行下一个拦截器
        MethodInterceptor interceptor = interceptors.get(++currentIndex);
        return interceptor.invoke(this);  // 递归调用
    }
}


6.2 从 Spring 源码学到的架构思想

1. 面向接口编程

// Spring 大量使用接口定义规范
BeanFactory → ApplicationContext → ConfigurableApplicationContext

// 好处:
// - 易于扩展(新增实现类)
// - 易于测试(Mock 实现)
// - 降低耦合

2. 扩展点设计

// Spring 提供大量扩展点,让框架具备高度可定制性
BeanPostProcessor        // Bean 初始化前后扩展
BeanFactoryPostProcessor // BeanFactory 初始化后扩展
ApplicationListener      // 事件监听扩展

3. 分层架构

接口层:定义规范(BeanFactory)
    ↓
抽象层:提供通用实现(AbstractApplicationContext)
    ↓
实现层:具体实现(AnnotationConfigApplicationContext)

4. 配置与代码分离

// 通过配置驱动,而不是硬编码
@Configuration
public class AppConfig {
    @Bean
    public DataSource dataSource() {
        // 配置数据源
    }
}


七、性能优化:Spring 容器调优

7.1 Bean 加载优化

问题: 容器启动慢,几千个 Bean 要加载几分钟?

优化方案 1:懒加载

// 只有在第一次使用时才创建
@Lazy
@Service
public class HeavyService {
    // 初始化很重的服务
}

优化方案 2:按需加载

@Configuration
@Profile("dev")  // 只在 dev 环境加载
public class DevConfig {
    @Bean
    public MockService mockService() {
        return new MockService();
    }
}

优化方案 3:异步初始化

@Component
public class AsyncBeanInitializer implements ApplicationListener<ContextRefreshedEvent> {
    
    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        // 容器启动完成后,异步初始化重型 Bean
        CompletableFuture.runAsync(() -> {
            heavyService.init();
        });
    }
}


7.2 AOP 性能优化

问题: 代理对象性能损耗?

对比测试:

// 原始方法调用:100万次 → 50ms
// JDK 代理调用:100万次 → 80ms(性能损耗 60%)
// CGLIB 代理调用:100万次 → 120ms(性能损耗 140%)

优化建议:

  1. 减少不必要的切面

// ❌ 不推荐:对所有方法都切
@Around("execution(* com.example..*.*(..))")

// ✅ 推荐:只对需要的方法切
@Around("@annotation(com.example.Log)")
  1. 使用 JDK 代理而不是 CGLIB

// 让目标类实现接口,优先使用 JDK 代理
public interface UserService {
    void createUser();
}

@Service
public class UserServiceImpl implements UserService {
    @Override
    public void createUser() {}
}
  1. 避免在高频方法上使用 AOP

// ❌ 不要在循环内的方法上加事务
for (int i = 0; i < 10000; i++) {
    transactionalService.save(data);  // 每次都开启/提交事务
}

// ✅ 批量操作在外层加事务
@Transactional
public void batchSave(List<Data> dataList) {
    for (Data data : dataList) {
        save(data);  // 复用同一个事务
    }
}


7.3 事务性能优化

问题 1:事务范围过大

// ❌ 不推荐:事务中包含耗时操作
@Transactional
public void processOrder() {
    Order order = saveOrder();  // 50ms
    
    callPaymentApi();  // 3000ms(网络调用)
    sendEmail();       // 2000ms(邮件发送)
    
    updateOrderStatus(order);  // 50ms
}
// 问题:事务持有数据库连接 5 秒!

优化:缩小事务范围

// ✅ 推荐:只在数据库操作时开启事务
public void processOrder() {
    Order order = orderService.saveOrder();  // 事务 1
    
    callPaymentApi();
    sendEmail();
    
    orderService.updateOrderStatus(order);  // 事务 2
}

问题 2:事务隔离级别过高

// ❌ 不必要的串行化隔离级别
@Transactional(isolation = Isolation.SERIALIZABLE)
public void query() {
    // 只是查询,不需要这么高的隔离级别
}

// ✅ 根据业务需求选择合适的隔离级别
@Transactional(isolation = Isolation.READ_COMMITTED)
public void query() {
    // 大部分场景用 READ_COMMITTED 足够
}


八、实战案例:手写简易版 Spring

为了加深理解,我们来手写一个简易版的 Spring IoC + AOP:

8.1 简易版 IoC 容器

public class SimpleApplicationContext {
    // Bean 容器
    private Map<String, Object> singletonObjects = new ConcurrentHashMap<>();
    
    // Bean 定义
    private Map<String, BeanDefinition> beanDefinitions = new ConcurrentHashMap<>();
    
    /**
     * 注册 Bean 定义
     */
    public void register(String beanName, Class<?> beanClass) {
        BeanDefinition bd = new BeanDefinition(beanClass);
        beanDefinitions.put(beanName, bd);
    }
    
    /**
     * 获取 Bean
     */
    public Object getBean(String beanName) {
        // 1. 先从缓存获取
        if (singletonObjects.containsKey(beanName)) {
            return singletonObjects.get(beanName);
        }
        
        // 2. 创建 Bean
        BeanDefinition bd = beanDefinitions.get(beanName);
        Object bean = createBean(bd);
        
        // 3. 属性注入
        populateBean(bean, bd);
        
        // 4. 初始化
        initializeBean(bean, beanName);
        
        // 5. 放入缓存
        singletonObjects.put(beanName, bean);
        
        return bean;
    }
    
    /**
     * 创建 Bean 实例
     */
    private Object createBean(BeanDefinition bd) {
        try {
            return bd.getBeanClass().getDeclaredConstructor().newInstance();
        } catch (Exception e) {
            throw new RuntimeException("创建 Bean 失败", e);
        }
    }
    
    /**
     * 属性注入
     */
    private void populateBean(Object bean, BeanDefinition bd) {
        // 获取所有字段
        Field[] fields = bean.getClass().getDeclaredFields();
        
        for (Field field : fields) {
            // 查找 @Autowired 注解
            if (field.isAnnotationPresent(Autowired.class)) {
                String fieldName = field.getName();
                Object dependentBean = getBean(fieldName);  // 递归获取依赖
                
                // 反射设置值
                field.setAccessible(true);
                try {
                    field.set(bean, dependentBean);
                } catch (Exception e) {
                    throw new RuntimeException("属性注入失败", e);
                }
            }
        }
    }
    
    /**
     * 初始化 Bean
     */
    private void initializeBean(Object bean, String beanName) {
        // 查找 @PostConstruct 注解的方法
        Method[] methods = bean.getClass().getDeclaredMethods();
        for (Method method : methods) {
            if (method.isAnnotationPresent(PostConstruct.class)) {
                method.setAccessible(true);
                try {
                    method.invoke(bean);
                } catch (Exception e) {
                    throw new RuntimeException("初始化方法执行失败", e);
                }
            }
        }
    }
}

// Bean 定义
class BeanDefinition {
    private Class<?> beanClass;
    
    public BeanDefinition(Class<?> beanClass) {
        this.beanClass = beanClass;
    }
    
    public Class<?> getBeanClass() {
        return beanClass;
    }
}

测试:

public class SimpleIoCTest {
    public static void main(String[] args) {
        SimpleApplicationContext context = new SimpleApplicationContext();
        
        // 注册 Bean
        context.register("userService", UserService.class);
        context.register("userRepository", UserRepository.class);
        
        // 获取 Bean
        UserService userService = (UserService) context.getBean("userService");
        userService.createUser();
    }
}

class UserService {
    @Autowired
    private UserRepository userRepository;
    
    @PostConstruct
    public void init() {
        System.out.println("UserService 初始化完成");
    }
    
    public void createUser() {
        System.out.println("创建用户");
        userRepository.save();
    }
}

class UserRepository {
    public void save() {
        System.out.println("保存到数据库");
    }
}


8.2 简易版 AOP

public class SimpleAopProxy {
    
    /**
     * 创建代理对象
     */
    public static Object createProxy(Object target, MethodInterceptor interceptor) {
        return Proxy.newProxyInstance(
            target.getClass().getClassLoader(),
            target.getClass().getInterfaces(),
            (proxy, method, args) -> {
                // 执行拦截器
                return interceptor.invoke(new SimpleMethodInvocation(target, method, args));
            }
        );
    }
}

// 方法拦截器
interface MethodInterceptor {
    Object invoke(MethodInvocation invocation) throws Throwable;
}

// 方法调用
class SimpleMethodInvocation implements MethodInvocation {
    private Object target;
    private Method method;
    private Object[] args;
    
    public SimpleMethodInvocation(Object target, Method method, Object[] args) {
        this.target = target;
        this.method = method;
        this.args = args;
    }
    
    @Override
    public Object proceed() throws Throwable {
        return method.invoke(target, args);
    }
}

interface MethodInvocation {
    Object proceed() throws Throwable;
}

测试:

public class SimpleAopTest {
    public static void main(String[] args) {
        // 创建目标对象
        UserService target = new UserServiceImpl();
        
        // 创建代理对象
        UserService proxy = (UserService) SimpleAopProxy.createProxy(target, invocation -> {
            System.out.println("方法执行前");
            Object result = invocation.proceed();
            System.out.println("方法执行后");
            return result;
        });
        
        // 调用代理对象
        proxy.createUser();
    }
}

interface UserService {
    void createUser();
}

class UserServiceImpl implements UserService {
    @Override
    public void createUser() {
        System.out.println("创建用户");
    }
}


九、总结与展望

9.1 核心要点回顾

IoC 容器:

  • Bean 生命周期的 11 个步骤

  • 三级缓存解决循环依赖

  • @Autowired 通过 BeanPostProcessor 实现

AOP 实现:

  • JDK 动态代理 vs CGLIB 代理

  • 拦截器链的责任链模式

  • 代理对象在 Bean 初始化后创建

事务传播:

  • 七种传播行为的应用场景

  • REQUIRES_NEW 用于独立事务

  • NESTED 用于嵌套事务(Savepoint)

9.2 学习建议

  1. 看源码的方法:

    • 先理解设计思想,再看实现细节

    • 抓住核心流程,忽略边界处理

    • 结合断点调试,追踪完整链路

  2. 从 Spring 学习架构设计:

    • 面向接口编程

    • 提供扩展点

    • 分层架构

    • 配置与代码分离

  3. 实践出真知:

    • 手写简易版 Spring

    • 阅读优秀开源项目

    • 在实际项目中应用

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

C_x_330

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值