创世纪:spring之初(第一日)

   第一日,上帝说要有光,于是有了光;

   第二日,上帝说要有水和空气,于是有了水和空气;

   第三日,上帝说要有植物,于是有了植物;

   第四日,上帝说要有日月星辰,于是有了日月星辰;

   第五日,上帝说要有鱼和鸟,于是有了鱼和鸟;

   第六日,上帝说要有飞虫走兽和人,于是有了飞虫走兽和人;

   第七日,上帝说累了,于是休息。

   从上帝造人可以看出来,上帝非常聪明,他没有在无任何基础的第一天先造人……上帝造人尚且需要七天,我们学习spring的骨架设计也得至少7天。

   第一天:

   在java届,有位名叫Rod Johnson的牛人,发现最初的java企业级开发处于混沌状态。

   于是,它决心编写一个能够解决问题的通用的基础架构。

   因为它深信面向接口编程能够将变化控制到最小,同时也利于扩展和变化。于是,它编写了如下的接口。 

  在混沌状态最先要创造的是一切对象的母亲BeanFactory,有了它,就能够得到一切它孕育的对象和属性,也就是说首先要造盖亚--大地之母。

   有了最初的母亲BeanFactory,johnson想,如果我要得到一组Bean对象而不单单是某个或某几个呢?另外,如果母亲的孩子也要孕育对象呢?于是,johnson创造了ListableBeanFactory以操作一组bean对象,比如getBeansOfType就能够根据得到同类型的一组Bean;创造了HierarchicalBeanFactory来解决多个BeanFactory的层次问题,比如getParentBeanFactory就能够得到BeanFactory的父Factory。

   这个BeanFactory最终是要在某个应用上使用的,那么,需要给予BeanFactory在一个应用中活动的能力。在BeanFactory中,只需要考虑跟bean相关的行为,比如怎么得到bean,bean的类型等;而如果要赋予其在应用中的能力,则就需要考虑更多,比如应用的名字,启动时间,id等等跟应用本身相关的行为和属性,于是johnson想到了创造ApplicationContext。johnson想,这个ApplicationContext一定要能做许多事,要能够处理参数化和国际化的文本信息,于是增加了MessageSource接口;要能发布事件以便解耦组件,于是有了ApplicationEventPublisher接口;要能得到资源文件,于是有了ResourcePatternResolver接口;要能有在不同环境有不同处理对象的能力,于是有了EnvironmentCapable接口。

   ApplicationContext继承了所有这些接口。

   但是最重要的是,无论是BeanFactory还是ApplicationContext,它们都需要有可配置的能力,于是有了子接口ConfigurableBeanFactory和ConfigurableApplicationContext;另外,web在当时是非常重要的趋势,而且相比其他应用有些独特,需要得到ServletContext,于是有了WebApplicationContext。

   到目前为止,johnson都是面向接口进行行为的抽象思考,并未具体实现他们。

   看着创造出来的BeanFactory和ApplicationContext,johnson意识到这一天的工作远远没有结束,因为并没有真正解决怎么能够让整套体系运转起来,于是,johnson开始思索如何实现他们。

   johoson首先想到的还是这个实现应该具备什么能力?当然要把之前提到的AutowireCapableBeanFactory,ListableBeanFactory和ConfigurableBeanFactory都包括进去。因此创造了ConfigurableListableBeanFactory。其次,需要考虑对于bean对象的几种能力,一是起别名的能力;二是保存单例对象的能力;三是缓存的能力;他们分别在SimpleAliasRegistry类,DefaultSingletonBeanRegistry类和FactoryBeanRegistrySupport类中实现。

   

  最终,创造出了DefaultListableBeanFactory,它是spring中一切ioc工厂的原型,是BeanFactory第一个真正的孩子,这个孩子非常重要,已经成为独立的创建ioc容器的基础,如果有扩展和使用,大多是继承它或者组合使用它。

  如果要初始化一个DefaultListableBeanFactory,可以用如下代码

ClassPathResource res = new ClassPathResource("applicationContext.xml");
		DefaultListableBeanFactory f = new DefaultListableBeanFactory();
		XmlBeanDefinitionReader r = new XmlBeanDefinitionReader(f);
		r.loadBeanDefinitions(res);

  接下来johnson想,BeanFactory有了一个功能比较全面的默认实现,那么ApplicationContext呢?于是johnson孜孜不倦的创造了3个重要的ApplicationContext实现:FileSystemXmlApplicationContext, ClassPathXmlApplicationContext, AnnotationConfigWebApplicationContext(其实还有很多,比如处理portlet的, 处理web的)


  johnson最先考虑的是如何去做spring的启动流程,它应该放到一个比较抽象的层次以便下层的所有类能够复用。于是他用一个AbstractApplicationContext实现了ConfigurableApplicationContext。还有一个很重要的功能,即将一个文件以资源的形式加载进来,这需要将资源抽象为Resource类,将定位资源的具体实现抽象到ResourceLoader,AbstractApplicationContext同样需要继承DefaultResourceLoader以提供这个功能。AbstractApplicationContext完成了整个启动流程(上帝将它安排在第二天完成),唯独没有做对BeanFactory的管理。于是,它的子类AbstractRefreshableApplicationContext专门做了这件事,实现了refreshBeanFactory, closeBeanFactory, getBeanFactory专门对BeanFactory的生命周期做了一些管理,但是AbstractRefreshableApplicationContext仍然没有加载所有配置好的Bean。到哪里加载配置好的资源,实际上到了下层的子类去做,比如FileSystemXmlApplicationContext,就是到文件系统去读一个xml形式的applicationContext;ClassPathXmlApplicationContext则是到类加载路径下去读这个applicationContext。而AnnotationConfigWebApplicationContext则从类文件的annotation中加载bean,spring的扫描也从此开始。

  看着主要的框架已经建立起来,johnson满意的笑着睡着了。

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值