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

前言

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

第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.0 xxxApplicationContext xxxApplicationContext AbstractRefreshableApplicationContext AbstractRefreshableApplicationContext FileSystemResource FileSystemResource refreshBeanFactory() getResourceByPath() FileSystemResource

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

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

(2)BeanDefinition的载入和解析

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

Created with Raphaël 2.1.0 AbstractApplicationContext AbstractApplicationContext AbstractRefreshableApplicationContext AbstractRefreshableApplicationContext DefaultListableBeanFactory DefaultListableBeanFactory XmlBeanDefinitionReader XmlBeanDefinitionReader BeanDefinitionParserDelegate BeanDefinitionParserDelegate refresh() 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.0 XmlBeanDefinitionReader XmlBeanDefinitionReader DefaultBeanDefinitionDocumentReader DefaultBeanDefinitionDocumentReader DefaultListableBeanFactory DefaultListableBeanFactory processBeanDefinition() registerBeanDefintion() beanDefinitionMap
2.3 IoC容器的依赖注入

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

Created with Raphaël 2.1.0 DefaultListableBeanFactory DefaultListableBeanFactory AbstractBeanFactory AbstractBeanFactory AbstractAutowireCapableBeanFactory AbstractAutowireCapableBeanFactory SimpleInstantiationStrategy SimpleInstantiationStrategy BeanDefinitionResolver BeanDefinitionResolver doGetBean() 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.0 FileSystemXmlBeanFactory FileSystemXmlBeanFactory AbstractApplicationContext AbstractApplicationContext prepareBeanFactory() 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.0 Servlet Servlet ContextLoaderListener ContextLoaderListener ContextLoader ContextLoader XmlWebApplicationContext XmlWebApplicationContext contextInitialized() initWebApplication() loadParentContext() createWebApplication() refresh() WebApplicationContext

(3)DispatcherServlet处理过程

Created with Raphaël 2.1.0 xx xx HttpServletBean HttpServletBean FrameworkServlet FrameworkServlet DispatcherServlet DispatcherServlet initServletBean() initWebApplication() onRefresh() initStrategies() doGet()/doPost() processRequest() doService() doDispatch()

(4)doDispatch协同模型

Created with Raphaël 2.1.0 DispatcherServlet DispatcherServlet HandlerMapping HandlerMapping HandlerInterceptor HandlerInterceptor HandlerAdapter HandlerAdapter ViewResolver ViewResolver View View checkMultipart() getHandler() HandlerExecutionChain preHandle() handle() ModelAndView postHandle() resolveViewName() getView() View render()
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值