【读过的书,留下的迹】Spring技术内幕——深入解析Spring架构与设计原理

本文深入探讨了Spring框架的核心组成部分,包括IoC容器的实现、初始化过程及依赖注入机制,同时覆盖了Spring AOP的实现原理及其关键概念,最后介绍了Spring MVC在Web环境中的部署与工作流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

  最近发现有时候看完一本书,时间久了容易忘记,看书不总结思考效果大打折扣,故打算写这一系列文章,一是为了整理书中的要点,帮助自己消化理解;二是勉励自己多看书思考。文章中不会把书中内容讲解的非常详细,只是总结概括,适合已经阅读过该书的读者。

第2章:IoC容器的实现

  • spring有各式各样的IoC容器的实现,每一个均实现了BeanFactory这个基本的接口
  • spring通过定义BeanDefiniton来管理基于spring的应用中的各种对象以及它们的依赖关系
2.1 BeanFactory 和 ApplicationContext
  • BeanFactory实现是IoC容器的基本形式
  • ApplicationContext实现是IoC的高级形式
    • 支持不同信息来源
    • 自带访问资源ResourceLoader
    • 支持应用实践
2.2 IoC容器的初始化过程
  • 简单来说,IoC容器的初始化是由容器的构造函数中的refresh()方法来启动的,这个方法标志IoC容器正式启动,包括
    • BeanDefinition的Resource定位
    • BeanDefinition的载入
    • 以及注册(将Definition转为spring的数据结构存储,HashMap)

(1)BeanDefinition的Resource定位

Created with Raphaël 2.1.0xxxApplicationContextxxxApplicationContextAbstractRefreshableApplicationContextAbstractRefreshableApplicationContextFileSystemResourceFileSystemResourcerefreshBeanFactory()getResourceByPath()FileSystemResource

ps:箭头代表方法委托给某个类实现

  • 主要方法是protected Resource getResourceByPath(String path)

(2)BeanDefinition的载入和解析

IoC容器对Bean的管理和依赖注入功能,是通过对其持有的BeanDefinition进行各种相关操作

Created with Raphaël 2.1.0AbstractApplicationContextAbstractApplicationContextAbstractRefreshableApplicationContextAbstractRefreshableApplicationContextDefaultListableBeanFactoryDefaultListableBeanFactoryXmlBeanDefinitionReaderXmlBeanDefinitionReaderBeanDefinitionParserDelegateBeanDefinitionParserDelegaterefresh()createBeanFactory()loadBeanDefinition()parseBeanDefinitionElement()
  • 通过IoC容器的refresh启动整个BeanDefinition的载入,初始化通过XmlBeanDefinitionReader来实现
    • XmlBeanDefinitionReader
    • 委托BeanDefinitionParserDelegate
    • 调用doLoadBeanDefinitions读取
    • 调用registerBeanDefinitions开始载入
    • 创建createBeanDefinitionDocumentReader
    • 调用parseBeanDefinitonElement解析
    • 形成BeanDefinition

(3)BeanDefinition在IoC容器中注册

经过载入和解析后,BeanDefinition信息已经在IoC容器中,但还不能直接提供使用,需对BeanDefinition进行注册,通过HashMap持有载入的BeanDefinition,提供更友好的使用,BeanDefinition都在beanDefinitionMap里被检索和使用

Created with Raphaël 2.1.0XmlBeanDefinitionReaderXmlBeanDefinitionReaderDefaultBeanDefinitionDocumentReaderDefaultBeanDefinitionDocumentReaderDefaultListableBeanFactoryDefaultListableBeanFactoryprocessBeanDefinition()registerBeanDefintion()beanDefinitionMap
2.3 IoC容器的依赖注入

IoC容器接口中的getBean方法是触发依赖注入发生的地方

Created with Raphaël 2.1.0DefaultListableBeanFactoryDefaultListableBeanFactoryAbstractBeanFactoryAbstractBeanFactoryAbstractAutowireCapableBeanFactoryAbstractAutowireCapableBeanFactorySimpleInstantiationStrategySimpleInstantiationStrategyBeanDefinitionResolverBeanDefinitionResolverdoGetBean()createBean()instantiate()populateBean()applyPropertyValues()resolveReference()
  • 依赖注入关系特别密切的方法有createBeanInstance(创建)和populateBean(依赖的注入)
    • 创建Bean有两种方法:一种通过BeanUtils,使用JVM的反射功能;一种通过CGLIB,字节码生成器的类库,提供了一系列API来提供生成和转换Java的字节码的功能
    • populatedBean包括:首先处理autowire注入,属性注入,通过BeanDefinitionResolver对Bean Reference解析注入(其实Bean Reference的解析就是一个递归调用getBean获取其他依赖Bean的过程)
2.4 容器的其他相关特性

(1)ApplicationContext初始化与销毁

Created with Raphaël 2.1.0FileSystemXmlBeanFactoryFileSystemXmlBeanFactoryAbstractApplicationContextAbstractApplicationContextprepareBeanFactory()addPropertyEditorRegister()addBeanPostPrecessor()doClose()closeBeanFactory()

(2)Bean的作用域

作用域描述备注
singleton在每个Spring IoC容器中一个bean定义对应一个对象实例随着ApplicationContext一起实例化
prototype一个bean定义对应多个对象实例调用getBean时实例化
request在一次HTTP请求中,一个bean定义对应一个实例;即每次HTTP请求将会有各自的bean实例, 它们依据某个bean定义创建而成。该作用域仅在基于web的Spring ApplicationContext 情形下有效只能用在基于web的Spring ApplicationContext
session在一个HTTP Session 中,一个bean定义对应一个实例。该作用域仅在基于web的SpringApplicationContext 情形下有效只能用在基于web的Spring ApplicationContext
global session在一个全局的HTTP Session 中,一个bean定义对应一个实例。典型情况下,仅在使用portlet context的时候有效。该作用域仅在基于web的Spring ApplicationContext 情形下有效只能用在基于web的Spring ApplicationContext

(3)Bean的生命周期

  • Bean实力创建
  • bean属性、依赖注入
  • 调用Bean的初始化方法
    • 调用一系列Aware接口,用来Bean对IoC容器的感知,如BeanNameAware、BeanFactoryAware、ApplicationContextAware
    • BeanPostProcessor,Bean后置处理器,用来监听事件发生,向容器注册后,具备接受IoC容器事件回调功能,两个接口
      • postProcessBeforeInitialization(),init-method前调用
      • postProcessAfterInitialization(),init-method后调用
    • 通过JDK的反射机制调用Bean的init-method进行初始化
  • 应用可以通过IoC容器使用Bean
  • 当容器关闭时,调用Bean的销毁方法
    • 若bean实现了DisposableBean接口,distroy()方法被调用
    • 如果指定了destroy-method=”close”定制的销毁方法,就调用这个方法

第3章:Spring AOP的实现

(1)流程

  • 利用反射技术以及第三方字节码技术,如CGLIB生成AopProxy代理对象
  • 根据配置中的Advisor配置拦截器
  • 将通知Advice适配成AdviceAdapter,以便调用

(2)概念

  • Advice通知
    • 定义在连接点做什么,为切面增强提供织入接口,如BeforeAdvice
  • Pointcut切点
    • 定义需要增强的方法集合,Pointcut接口中需返回一个MethodMatcher
  • Advisor通知器
    • 把Advice和Pointcut结合起来,完成Advisor

(3)原理

  • Spring AOP代理对象生成
    • Spring提供了两种方式来生成代理对象::JDKProxy和Cglib,具体使用哪种方式生成由AopProxyFactory根据AdvisedSupport对象的配置来决定。默认的策略是如果目标类是接口,则使用JDK动态代理技术,否则使用Cglib来生成代理
  • AopProxy类中的invoke方法
    • 获取可以应用到此方法上的通知链(Interceptor Chain),如果有,则应用通知,并执行joinpoint;如果没有,则直接反射执行joinpoint。
  • invoke中的getInterceptorsAndDynamicInterceptionAdvice
    • 从提供的配置实例config中获取advisor列表,遍历处理这些advisor。如果是IntroductionAdvisor,则判断此Advisor能否应用到目标类targetClass上。如果是PointcutAdvisor,则判断,此Advisor能否应用到目标方法method上。将满足条件的Advisor通过AdvisorAdaptor转化成Interceptor列表(拦截器列表)返回。这一步Advisor被适配成AdvisorAdapter,即拦截器

第4章:Spring MVC与Web环境

(1)Web环境中的Spring MVC

  • 需要在web.xml中配置两个类
    • ContextLoaderListener:IoC容器的初始化
    • DispatchServlet:处理web请求的转发

(2)IoC容器的启动

Created with Raphaël 2.1.0ServletServletContextLoaderListenerContextLoaderListenerContextLoaderContextLoaderXmlWebApplicationContextXmlWebApplicationContextcontextInitialized()initWebApplication()loadParentContext()createWebApplication()refresh()WebApplicationContext

(3)DispatcherServlet处理过程

Created with Raphaël 2.1.0xxxxHttpServletBeanHttpServletBeanFrameworkServletFrameworkServletDispatcherServletDispatcherServletinitServletBean()initWebApplication()onRefresh()initStrategies()doGet()/doPost()processRequest()doService()doDispatch()

(4)doDispatch协同模型

Created with Raphaël 2.1.0DispatcherServletDispatcherServletHandlerMappingHandlerMappingHandlerInterceptorHandlerInterceptorHandlerAdapterHandlerAdapterViewResolverViewResolverViewViewcheckMultipart()getHandler()HandlerExecutionChainpreHandle()handle()ModelAndViewpostHandle()resolveViewName()getView()Viewrender()
×××总共两个zip文件;7zip压缩 ×××Spring 技术内幕.zip.001 ×××Spring 技术内幕.zip.002 本spring领域的问鼎之作,由业界拥有10余年开发经验的资深java专家亲自执笔!java开发者社区和spring开发者社区一致强烈推荐。.    国内第一本基于spring3.0的著作,从源代码的角度对spring的内核和各个主要功能模块的架构设计和实现原理进行了深入剖析。你不仅能从木中参透spring框架的优秀架构设计思想,而且还能从spring优雅的实现源码中一窥java语言的精髓。此外,本还展示了阅读源代码的卓越方法,不仅授你以鱼,而且还授你以渔!..    如果你以一种淡定的心态翻开这本,无论你是java程序员、spring开发者,还是平台开发人员、系统架构师,抑或是对开源软件源代码着迷的代码狂人,都能从本中受益。    作者从业10余载,悟透spring等开源软件的本质,权威性毋庸置疑。    java开发者社区、专业spring开发者社区和架构师社区一致鼎力推荐!    深入解析spring架构原理设计思想,探究spring成功的奥秘。    揭开spring源代码的神秘面纱,展示系统阅读开源软件源代码的方法和秘诀。    掌握spring架构原理设计思想真的能让开发者如虎添翼吗?    ioc容器如何掌控以pojo为基础的bean对象?它的轻量级开发设计思想是如何实现的?    spring产品级的ioc容器是如何作为一个完整的系统实现并运行的?它如何启动?如何完成bean的解析和载入?又如何实现bean的生命周期管理?    spring如何简捷地在jvm上实现aop功能?    spring aop如何实现aspect编织功能?    spring如何实现各种数据库操作组件的集成?    spring如何在web环境中集成ioc容器并为web应用开发提供利器?    我们耳熟能详的mvc模式在spring中是如何实现的?    spring mvc如何灵活地集成各种丰富的视图展现方案?    spring实现远端调用的方案有很多种,你知道它们之间的优劣差异吗?    spring acegi安全框架在用户验证和授权机制的实现上有何过人之处?    如何在spring的基础上进行扩展开发?    你是否曾经也有过分析开源软件源代码的冲动?你想掌握分析源代码的最佳实践吗?
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值