最近在做一些项目集成的工作,不同的项目分支有一些相同的功能模块但是需要集成不同的第三方公司的应用。项目引入的Spring并基于Spring进行了构建。而Spring对于我现在正在做的集成工作是再适合不过的了,所以从基础开始系统学习一下Spring来更好的完成集成工作,使得今后其他新上线项目进行集成的时候不需要修改原有的项目代码,而只需修改相关的配置文件即可。因为平时用到的东西很多,但不会经常用到,记录笔记后当再次使用的时候看看自己的笔记对于快速进行工作很有帮助。

Spring已经成为目前JAVA开发中非常重要的框架,Spring是个开源的应用框架,以前就知道Spring的主要思想就是“依赖注入”(dependency injection / DI)或者叫做 “控制反转”(Inversion of contro / IoC)但是看了一下资料,很抽象,也因为当时没有用到Spring而没再深究。仔细阅读了下资料跟示例后,按我的理解Spring中的“依赖注入”是指在程序中可能发生变动的地方应用Spring,将变动部分写到Spring的配置文件中。在将来放生变动时不用对现有的类进行改动,而只需要对Spring的配置文件进行改动即可。一个比较容易理解的例子,比如一个负责进行数据库持久化的类PersistentCclass,这个类中需要使用到数据源来建立数据库连接,因此一般来说需要 new 一个实现了某个DataSource接口的数据源对象,而当某个时候需要使用另外一个实现了DataSource接口的类来进行替换的时候我们只能回到PersistentCclass中修改new 后边的我们之前使用的类。(也许工厂模式可以提升此段代码的扩展性,但变动时同样需要修改原先的工厂类)。对于这种情况如果使用Spring的话,我们只需要修改Spring的配置文件即可(对于Spring2.5及以后的版本,使用了JAVA5及以上版本的话支持使用Annotation),而不需要改动原先写好的类。

使用Spring在PersistentCclass中代码片段如下:

// ClassPathXmlApplicationContext这个类是Spring jar包中的类实际上是ApplicationContext接口的实现类
ApplicationContext spring = new ClassPathXmlApplicationContext("针对于包结构的xml文件路径");
DataSouece dataSource = (DataSource)spring.getBean("dataSourceName")

从上边的代码可以看到,不再使用new来创建我们需要的对象,而是使用Spring配置文件中配置的名字"dataSourceName"(id或者name)通过getBean方法来获取对象,从这点来看Spring充当了工厂的角色。这样不论dataSource需要引用的对象如何变化,我们都不再需要修改这段代码,只需要修改Spring的配置文件中“dataSourceName”名字对应实际的类即可。

还有一种场景,Spring对于单元测试是很方便的。我们可以很容易的使用Spring的配置文件将程序中使用到的其他类改为我们模拟的用来测试的类,来对另外一个需要进行测试的类类进行测试,而不用考虑我们的Server以及数据连接的一些情况。

Spring并不会简化我们的代码,而是会使我们的应用更易扩展及维护。一般来说如果项目应用中引入了某个框架,那整个应用对这个框架的依赖性将是是非常强的,我们需要了解这个框架的API以及各种使用方法。而Spring不是这样,我们可以很容易的在已经开发完成的应用上增加Spring特性,来对我们的应用进行维护(也就是我现在做的集成工作遇到的情况,即使集成工作的应用之前没有用到Spring,我也可以使用Spring来进行我的集成工作),而已经存在的部分甚至跟新加入的Spring可以没半点儿关系。Spring使应用具有更好的维护性跟扩展性,但不意味着整个应用处处都要用到Spring来进行配置,可以将可能发生变动的部分代码来使用Spring进行配置。如果整个应用都依赖Spring进行开发反而会增加维护的难度跟额外的工作量。