当前位置: 首页 > news >正文

Sprinig源码解析

前言

  Spring 框架是 Java 企业级开发的基石,其源码设计体现了模块化、扩展性和灵活性。以下从 IoC 容器、AOP 实现、核心模块和关键设计模式四个角度对 Spring 源码进行深度解析,帮助理解其底层机制。即使Spring会使用的人见得就能使用。

一、IoC 容器源码解析

  IoC(控制反转)是 Spring 的核心,其核心接口是 BeanFactory 和 ApplicationContext。

1.1. Bean 的生命周期

  Spring 管理 Bean 的完整生命周期,关键步骤如下:
1.Bean 定义加载:

  • 通过 BeanDefinitionReader(如 XmlBeanDefinitionReader)读取 XML 或注解配置,解析为 BeanDefinition 对象。
    2.Bean 实例化:
  • 调用 InstantiationStrategy(默认 CglibSubclassingInstantiationStrategy)创建 Bean 实例。
  • 反射或 CGLIB 动态生成子类(用于处理构造方法注入或 AOP 代理)。
    3.依赖注入:
  • 通过 AutowiredAnnotationBeanPostProcessor 处理 @Autowired 注解。
  • 使用 CommonAnnotationBeanPostProcessor 处理 @Resource 等 JSR-250 注解。
    4.初始化:
  • 调用 InitializingBean.afterPropertiesSet() 或自定义 init-method。
  • 应用 BeanPostProcessor.postProcessBeforeInitialization() 和 postProcessAfterInitialization()。
    5.销毁:
  • 调用 DisposableBean.destroy() 或自定义 destroy-method。

1.2. BeanFactory 与 ApplicationContext

  • BeanFactory:
  • 基础容器接口(DefaultListableBeanFactory 是默认实现)。
  • 延迟加载 Bean,首次调用 getBean() 时实例化。
    ApplicationContext:
  • 扩展自 BeanFactory,提供企业级功能(国际化、事件发布、资源加载等)。
  • 默认在启动时预初始化所有单例 Bean(通过 AbstractApplicationContext.refresh())。

1.3. 源码流程示例

// 核心入口:AbstractApplicationContext.refresh()
public void refresh() {
    // 1. 加载 BeanDefinition
    obtainFreshBeanFactory();
    // 2. 调用 BeanFactoryPostProcessor
    invokeBeanFactoryPostProcessors();
    // 3. 注册 BeanPostProcessor
    registerBeanPostProcessors();
    // 4. 初始化单例 Bean
    finishBeanFactoryInitialization(beanFactory);
}

二、AOP 实现源码解析

Spring AOP 基于动态代理实现,支持 JDK 动态代理和 CGLIB。

2.1. AOP 核心组件

  • Pointcut:定义切点(哪些方法需要被增强)。
  • Advice:定义增强逻辑(前置、后置、环绕等)。
  • Advisor:组合 Pointcut 和 Advice。
  • AopProxy:生成代理对象的接口(JdkDynamicAopProxy 或 ObjenesisCglibAopProxy)。

2.2. 代理创建流程

  1.在 Bean 初始化阶段,AbstractAutoProxyCreator(实现 BeanPostProcessor)拦截 Bean 的创建。
  2.根据 Pointcut 匹配 Bean 的方法,生成代理对象。
  3.调用代理对象的方法时,触发 MethodInterceptor 链式执行。

2.3. 源码示例

// JdkDynamicAopProxy 的 invoke() 方法
public Object invoke(Object proxy, Method method, Object[] args) {
    // 获取拦截器链
    List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
    // 创建 MethodInvocation 并执行
    MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
    return invocation.proceed();
}

三、核心模块解析

3.1. 事务管理(@Transactional)

  • 实现原理:

    • 通过 TransactionInterceptor 拦截方法调用。
    • 使用 PlatformTransactionManager(如 DataSourceTransactionManager)管理事务。
  • 关键代码:

// TransactionAspectSupport.invokeWithinTransaction()
protected Object invokeWithinTransaction(Method method, Class<?> targetClass, final InvocationCallback invocation) {
    TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
    try {
        Object result = invocation.proceedWithInvocation();
        commitTransactionAfterReturning(txInfo);
        return result;
    } catch (Throwable ex) {
        completeTransactionAfterThrowing(txInfo, ex);
        throw ex;
    }
}

3.2. 事件机制(ApplicationEvent)

  • 核心类:

    • ApplicationEventPublisher:发布事件。
    • ApplicationListener:监听事件。
  • 流程:

    • 调用 publishEvent() 发布事件。
    • 通过 SimpleApplicationEventMulticaster 广播事件到所有匹配的监听器。

3.3. SpEL(Spring Expression Language)

  • 解析流程:
    • 使用 SpelExpressionParser 解析表达式。
    • 通过 StandardEvaluationContext 提供上下文变量。

四、关键设计模式

  1. 模板方法模式
  • 应用场景:AbstractApplicationContext.refresh() 定义了容器初始化的骨架,子类可重写特定步骤(如 AnnotationConfigWebApplicationContext)。
  • 示例代码:
public abstract class AbstractApplicationContext {
    public void refresh() {
        // 模板方法
        obtainFreshBeanFactory();
        prepareBeanFactory(beanFactory);
        postProcessBeanFactory(beanFactory);
        // ...
    }
}
  1. 工厂模式
  • 应用场景:BeanFactory 是工厂接口,DefaultListableBeanFactory 是具体实现。
  1. 代理模式
  • 应用场景:AOP 动态代理、ProxyFactoryBean 创建代理对象。
  1. 观察者模式
  • 应用场景:事件发布与监听机制。

五、调试 Spring 源码的建议

1.入口示例:

// 基于注解的容器初始化
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
UserService userService = context.getBean(UserService.class);
userService.save();

2.关键断点:

  • AbstractApplicationContext.refresh():容器初始化的核心入口。
  • AbstractAutowireCapableBeanFactory.createBean():Bean 实例化的关键逻辑。
  • JdkDynamicAopProxy.invoke():AOP 代理方法调用。
  • TransactionInterceptor.invoke():事务管理的拦截逻辑。

六、Spring 源码设计哲学

  1.开闭原则:通过扩展点(如 BeanPostProcessor)支持功能扩展,无需修改核心代码。

  2.单一职责:模块高度解耦(如 BeanFactory 负责 Bean 管理,ApplicationContext 提供企业级功能)。

  3.约定优于配置:通过默认配置减少用户工作量(如自动扫描 @Component 注解)。

总结

  Spring源码通过模块化设计和经典设计模式实现了高度灵活性和扩展性:

  • IoC 容器:以 BeanFactory 为核心,通过 BeanDefinition 和 BeanPostProcessor 管理 Bean 生命周期。
  • AOP:基于动态代理和拦截器链实现切面编程。
  • 事务与事件:通过拦截器和观察者模式提供企业级功能。
  • 扩展机制:开放 BeanFactoryPostProcessor、BeanPostProcessor 等扩展点。

  深入Spring源码不仅能帮助解决实际开发中的复杂问题(如性能优化、定制化需求),还能提升对框架设计思想的理解,为开发高质量应用奠定基础。

相关文章:

  • 3D模型可视化引擎HOOPS Visualize在桌面端的支持有哪些特点?
  • 【LINUX】常用指令查询
  • 第五章 起航10 金字塔原理
  • ollama部署deepseek实操记录
  • 设备智能AI语音交互,ESP32-S3芯片方案应用,物联网无线联动控制
  • Next.js【详解】CSS 样式方案
  • C#搜索算法大冒险:在数据海洋里找宝藏
  • 什么是神经网络?
  • Docker 镜像标签使用
  • ICRA-2025 | 具身导航如何跨越地形障碍?SARO:通过视觉语言模型实现地形穿越
  • Debian系发行版通用软件彻底卸载指南
  • 游戏引擎学习第102天
  • C语言——排序(冒泡,选择,插入)
  • leetcode18-四数之和
  • 百度舆情优化:百度下拉框中的负面如何清除?
  • Golang学习历程【第七篇 闭包type defer panic recover了解time包】
  • Redis中的某一热点数据缓存过期了,此时有大量请求访问怎么办?
  • Docker 镜像的构建与管理(二)
  • 比亚迪“璇玑架构”和特斯拉FSD的比较
  • 第一章:Matlab 基础入门
  • 魔都眼|咖啡节上上海小囡忍不住尝了咖啡香,母亲乐了
  • 体坛联播|曼联一只脚迈进欧联杯决赛,赵心童4比4奥沙利文
  • 韩国代总统、国务总理韩德洙宣布辞职,将择期宣布参选总统
  • 贵州锦屏县委原书记舒健已任黔东南州政府办主任
  • 当农民跨进流动的世界|劳动者的书信①
  • 北京亦庄启动青年人才创新创业生态示范区