编辑器加载中...

Spring学习笔记<原创>

——本篇属于原创文章,若转载请标明出处。

一、认识Spirng

1.1 术语描述

1.1.1 轻量级(Lightweight)

轻量级是相对于重量级容器(EJB)来说,Spring的核心包在文件容量上只有不到1MB的大小。

1.1.2 非入侵性(No intrusive

有些框架一旦被开发人员使用,则会使应用程序对框架有了依赖性。例如大量使用框架的API,或者直接继承框架的默写类型等。无法使应用程序从框架中独立出来,更别说移植了。

Spring的非入侵性,增加应用程序组件的可重用性。简单的说,使用Spring,应用程序中的某些组件可以直接拿到另一个应用程序或者框架之中使用。

1.1.3 容器(Container

容器可以管理对象的生成,资源取得,销毁等,建立对象与对象之间的依赖关系。Spring的容器,可以使用配置文件(通常是XML)来管理当中的对象。当启动容器之后,所有的对象都可以直接取用,不用编写任何一行程序代码来产生对象,或是建立对象之间的依赖关系。原先必须编写程序来管理对象关系,现在容器都会自动做好。

1.1.4 控制反转(Ioc

Spring最重要的核心概念是控制反转(Inversion of Control)。稍后详细描述。

1.1.5 依赖注入(DI

另一个重要概念为依赖注入(Dependency Injection)。使用Spring,不必自己在程序代码中维护对象的依赖关系,只需在配置文件中设置。Spring容器会根据配置,自动将依赖注入指定到指定的对象。

1.1.6 面向切面(AOP

AOPSpring的一个子框架。假设应用程序有个日志(Logging)的需求,你可以无需修改任何一行代码,就可以将这个需求加入至原先的应用程序中,也可在不修改任何代码的前提下将其从程序中移除。

SpringIoC容器功能与AOP功能的实现是其重心所在,在Spring中的持久层、MVC Web框架以及各种企业服务的API封装,它们的实现有些依赖于SpringIoC容器与AOP功能。Spring的这些子框架可以互相独立,也可以结合其他框架加以代替。

1.1.7 持久层

Spring提供对持久层的整合,如对JDBC加以封装和简化,提供程式事务和声明式事务。对于O/R Mapping工具(如Hibernate)的整合以及使用上的简化都提供了方案。

1.1.8 Web框架

Spring也提供Model2Web MVC)框架的解决方案,使用Spring Web框架的好处是可以利用其本身的IoCAOP功能,轻松的替换使用不同的View层技术。

1.1.9 其他企业服务的封装

对于一些服务,如JNDIMail、计划任务、远程等,Spring不提供直接的实现,而是采取抽象层方式对这些服务进行封装,让这些服务有一致的使用模型,并且在使用上更为简化。

1.2 控制反转(IoC

Spring的核心概念是控制反转,IoC的抽象概念是“依赖关系的转移”。转移是相对与过去的不良程序设计而言。IoC的具体表现:

1、高层模块不应该依赖于低层模块,而模块都必须依赖于抽象。

2、实现必须依赖抽象,而不是抽象依赖实现。

3、应用程序不应该依赖容器,而是容器服务于应用程序。

简单的说,在进行模块设计时,高层的抽象模块通常是与业务逻辑相关的模块,它应该具有重用性,而不依赖于低层的实现模块。例如高层模块是存储数据的需求,而低层模块可能是与硬件相关的软盘存储设计。如果高层模块直接调用执行低层模块的实现API,就对低层模块产生了依赖。如果要求将数据存储至U盘,则高层模块无法直接重用,必须修改才行。这不是一个好的设计,不能达到模块的重用性。

依赖反转可以解决这个问题:程序不应该依赖实现,而是依赖抽象接口。以java程序为例:

Private class Business

private FloppyWriter writer = new FloppyCopy();

public void  save()

{

writer.saveToFloppy();

}

在这个业务逻辑类中,要求存储到软盘FloppyWriter对象,但是如果有一天要存储至U盘。则必须修改Business的程序,因此没有做到模块复用。

通过依赖抽象接口,可以解决这一情况。先把存储介质不变公有的特性抽象出来,即存储这个动作,抽象成一个接口:IWriter

public interface IWriter{

public void saveToDevice();

}

接着设计业务逻辑模块Business。使其依赖于不变的轴线抽象接口,而不是依赖于具体实现。例如:

public class Business

{

private IWriter writer;

public void setWriter(IWriter writer)

{

this.writer = writer;

}

public void save()

{

writer.saveToDevice();

}

在这样的设计下,Business是可重用的。只要针对不同需求实现IWriter即可。使不同的具体实现实现接口,使其有合同行为。例如:

public class FloppyWriter implement IWriter

{

public void savaToDevice()

{

//.......实际存储至软盘的程序代码

}

}

public class USBWriter implement IWriter

{

public void savaToDevice()

{

//.......实际存储至U盘的程序代码。

}

}

则客户程序这样写:

Business business = new Business();

business.setWriter(new FloppyWriter());

如果需求发生变化,要求存储至U盘,则:

business.setWriter(new USBWriter());

business.save();

即可。

其中也可以使用配置文件来更改配置。做到客户程序无需发生任何变化。

上述为控制反转的思想,让抽象的模块拥有控制权。可以获得组件的复用。即让控制权从FloppyWriter转到IWrter。让Business依赖于IWriterUSBWriterFloppyWrter也依赖于IWriter

IoC在容器中扮演的角色,可以用这么一句好莱坞名言表示:“Don't call me,I'll call you”。即现在的好莱坞法则。以程序来讲就是不要向容器要求所需要的对象资源,容器会自动将这些对象给您。

IoC的要求是容器不应该侵入应用程序,也就是不应出现于容器相依的API。应用程序可以依赖抽象的接口,容器可以通过这些抽象的接口将所需要的资源注入至应用程序中。应用程序不向容器主动要求资源,故而不会依赖于容器特定的API,应用程序本身不会意识到正被容器使用,故而可以随时从容器系统中脱离,转移至其他框架而不需要任何修改。

1.3 依赖注入(DI

IoC模式基本上是一个高层的模式概念,实现IoC有两种方式:Dependency InjectionService LocatorSpring 所采用的是用Dependency Injection来实现IoC,即依赖注入。

依赖注入的意义是:“保留抽象接口,让组件(Component)依赖于抽象接口,当组件要与其他实际的对象发生依赖关系时,由抽象接口来注入依赖的实际对象。”

依赖注入有3种实现方式:Interface injectionSetter injectionConstructor injection。刚才使用的是第二种方式。

第三种方式是构造器注入例如:

public class Business

{

private IWriter writer;

public Business(IWriter writer)

{

this.writer = writer;

}

public void save()

{

this.writer.saveToDevice();

}

}

推荐使用第二种方式和第三种方式。不推荐使用第一种方式。因为第一种方式要实现容器指定的接口,使程序依赖于容器(框架),使其无法从容器中脱离。从而具有侵入性。

Spring的核心是IoC容器,可以管理对象的生命周期,并可以通过setter或构造器的方式,编写配置文件(一般为XML文件),让Spring在执行时期根据配置文件的设定,创建对象之间的依赖。不必自己写工厂代码来建立对象之间的依赖。

 

posted on 2012-03-30 19:08  LifeStudio  阅读(224)  评论(0编辑  收藏  举报