Spring知识梳理

前言

最近在看Spring的源码,非常头大,因为能力有限不准备对源码进行很深的研究,只是希望在这里将大概原理做一个梳理,以应付面试用,待以后再深入学习Spring的源码吧。

Spring的设计理念

在JAVA EE的开发中,支持使用POJO和JavaBean的开发方式,使应用面向接口开发,充分支持OO(面向对象)的设计方法。(现在还不太能理解这句话的意思,也许需要比较传统的EJB开发模式才能体会出Spring的方便之处)。Spring作为平台的一大优点,就是针对JAVA代码的解耦。他可以允许我们通过一个或者几个XML文件对JAVA中的耦合关系进行预览和相关操作,同时通过IOC容器实现的依赖反转,把依赖关系的管理从JAVA对象中解放出来交给IOC容器(或者说Spring框架)来完成,从而完成了对象之间的解耦,原来的对象-对象的关系变成了对象-IOC容器-对象的关系。

Spring的价值

1.Spring是一个非侵入式的框架。他会尽量将应用程序代码对框架的依赖最小化,使之在没有框架的情况下依旧可以运行。(没有感觉,可能理解不深)。
2.Spring提供了一个一致的编程模型,让应用直接使用POJO开发,从而与运行环境(如服务器)隔离开来。
3.Spring推动设计风格向面向对象面向接口转变。
4.Spring是一个开放式的平台,他允许我们选择其他诸多组件,比如Mybatis。

IOC容器和依赖反转

什么是依赖反转?即创建对象的义务被容器接管,业务逻辑代码中无需再考虑依赖对象的创建,所以也叫依赖注入,将对其他对象的依赖注入到现在对象中。比如以前我们需要在UserService中使用WalletService,需要写如下代码:WalletService walletService = new WalletService(),但当我们需要将WalletService中的构造函数改为有一个String参数时,就需要将每一个上述代码修改为这样WalletService walletService = new WalletService("str"),这无疑增加了我们的工作量,而依赖反转帮助我们解决了这个问题,我们不管对WalletService进行如何更改,IOC容器都会帮助我们将依赖注入到我们操作的对象中。Spring框架最主要的主体就是IOC容器,其他的例如AOP都是他提供的功能,所以有的时候我们称呼Spring框架为IOC容器也并不过分。

IOC容器的初步实现:BeanFactory

我们把IOC容器比作一个水桶,水桶需要有他自己的定义才能被叫为水桶,比如圆柱形上面无盖能装水等等,而BeanFactory就是对水桶最基本的定义规则。其他继承他的接口比如ListableBeanFactory是一些扩展定义规则,比如木制水桶规定需要材质为木头等等。真正的水桶产品是实现这些接口的实现类,比如我们经常用到的DefaultListableBeanFactory,他代表一个实实在在的产品,比如木制水桶,DefaultListableBeanFactory可以看做是一个功能完备的IOC容器实例,可以供我们进行使用,其他IOC容器都是在他的基础上进行的功能扩展,比如XMLBeanFactory等。IOC中的BeanFactory接口体系设计的非常灵活,他基本上将每一个不同的点都设计成接口以便复用和扩展,所以我们最后看到的水桶规则其实是很多细小规则累加之后的产品。下面的一段代码表示IOC容器的启动:

//Spring中的Resource代表着各种资源对象,我们知道Spring需要在例如XML的文件中进行很多配置,Resource就是Spring将这些配置文件封装成的对象
ClassPathResource resource = new ClassPathResource("beanFactoryTest.xml");

//实例化Factory,这里相当于已经启用了一个无用的、空的IOC容器
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();

//我们需要将Resource中的配置信息放到Factory中以供Factory使用,XmlBeanDefinitionReader就是读取Resource中信息的对象
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);

//调用XmlBeanDefinitionReader对象的loadBeanDefinitions方法,将配置信息写入Factory,这时候Factory已经有了我们的相关设置,已经达到了使用的标准
reader.loadBeanDefinitions(resource);

IOC容器的高级实现:ApplicationContext

ApplicationContext也是IOC系统的实现方法,他比BeanFactory更高级,BeanFactory 使用的时候我们还需要进行其他的操作,比如将设置传入BeanFactory等等,但ApplicationContext已经自带了这些功能,就无需我们再关心这些事情。我们以FileSystemXmlApplicationContext为例,在初始化的过程中是调用AbstractApplicationContext类中的refresh()方法来启动整个BeanDifinition的载入过程的,这个初始化是通过XmlBeanDefinitionReader来完成,IOC容器实际上使用的是DefaultListableBeanFactory,具体的Resource载入在XmlBeanDefinitionReader读入BeanDifinition时实现。

IOC容器的初始化过程

  1. Resource的定位过程。这个定位过程其实就是BeanDefinition的资源定位,他由ResourceLoader通过统一的Resource接口来完成。从名称就可以知道他的实现类是做什么用的,比如:ClassPathResource是从根路径中查找配置资源。这个过程就相当于打水的时候先把水找到。关于XML资源类型的资源定位是在XmlBeanDefinitionReader类中的loadBeanDefinitions(EncodedResource encodedResource)方法中进行实现的。感兴趣的自己可以再查找资料好好了解一下。
  2. BeanDifinition的载入和解析。这个载入过程就是将用户定义好的bean表示成IOC容器内的数据结构,他实际上就是POJO对象在IOC容器里的抽象,通过BeanDifinition,IOC可以很方便的对POJO对象也就是Bean进行管理。IOC容器是通过一个HashMap来保持和维护这些BeanDifinition的。如果把IOC容器比作是水桶的话,那BeanDifinition就是水桶里的水。BeanDifinition的载入就相当于我们把水倒入水桶中。这个载入过程也是在XmlBeanDefinitionReader类中的loadBeanDefinitions(EncodedResource encodedResource)方法中进行实现的,如果是ApplicationContext的启动方式,则是在AbstractXmlApplicationContext类中的loadBeanDefinitions(XmlBeanDefinitionReader reader)方法中调用了XmlBeanDefinitionReader类中的loadBeanDefinitions(EncodedResource encodedResource)方法。解析是在DefaultBeanDefinitionDocumentReader类中的processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate)方法中实现。
  3. .BeanDifinition的注册。在BeanDifinition载入IOC容器之后,我们需要将BeanDifinition向IOC容器进行注册,这里你可以这样理解,我们将水装入水桶后需要告诉一下水桶,这样水桶才知道里面已经装了水,这个过程是调用BeanDifinitionRegistry接口的实现来完成的,在IOC内部将BeanDifinition注入到一个HashMap中去。

SpringMVC启动的基本过程

IOC的启动过程就是上下文的启动过程,该上下文是与ServletContext相伴而生的,同时也是IOC容器在WEB应用环境中的具体表现之一。由ContextLoaderListener启动的上下文为根上下文,在根上下文的继承下还有一个与WEB MVC相关的上下文用来保存控制器(DispatcherServlet)需要的MVC对象,作为根上下文的子上下文。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值