spring的核心是ioc, 即控制反转(依赖注入)
ioc:
我们拿数据存储为例:
1. 实现数据存储的一般思路:定义一个Database类进行数据库的操作,定义一个business业务逻辑类,调用database类及方法。
实现如下:
public class Database{ //向数据库中存储数据 public void saveDB(){}; } public class Business{ private Database db = new Database; //从数据库中获取数据 public void saveData(){ .. db.saveDB(); }
2. 这样做,每次业务需求变动将导致程序大量修改,是不好的设计方案。
3. 利用ioc的解决思路是:首先编写一个存储数据的接口,然后每个具体负责存储数据的类都实现这个接口。而在业务逻辑类business中,则针对数据的接口编程,并不与存储数据的类建立任何联系。这样,存储方式的变化就不会要修改业务逻辑类了。
set方式注入的代码实现步骤如下:
首先编写涌来存储数据的接口SaveData,该接口中定义了saveData()涌来负责存储数据,每一个具体负责存储数据的类都要实现这个方法,而业务逻辑类只针对接口中的savedata()方法编程。
public interface SaveData { //该方法用来存储数据 public void saveData(); }
接下来,编写负责具体向数据库存储数据的DataBase类,该类实现了savedata接口。
public class DataBase implement SaveData{ //该方法用来存储数据 public void saveData (){ //具体负责存储数据的代码 .. } }
编写business类,不针对实体类。
public class Business { //针对接口savedata定义变量 private SaveData db; public void setSaveData (SaveData db){ this.db = db; } .. //根据注入的存储类,存储数据 public void saveData() { .. db.saveData(); } }
测试类:
public class TestBusiness { private Business business = new Business (); .. // public void saveData (){ .. business.setSaveData (new DataBase ()); business.saveData (); .. } }
优点:通过这种方式,business类就可以重用了,不管采用xml,database等方式都可以存储数据。business类都不用改动,只需要实现具体的savedata接口就行了。
可见ioc的强大之处在于,面向接口编程,使得业务逻辑代码实现了重用,从而实现了如果不是业务逻辑发生变化,就不需要修改业务逻辑的相关代码。
接口注入:
接口注入指在接口中定义要注入的信息,并通过接口完成注入。改动步骤如下:
编写business接口,各种存储方式的注入将通过这个接口进行。
public interface Business { public void DiSaveData (SaveDara db) ; } 负责业务逻辑的类都不许实现这个接口。 public class BusinessImpl implement Business { private SaveData db; public void DiSaveData (SaveData db) { this.db = db; } .. //根据注入的存储类,存储数据 public void saveData (){ .. db.saveData(); .. } }
测试类。
public class TestBusiness { private Business business = new BusinessImp (); .. //根据注入的存储类,存储数据 public void opraDara () { .. business.DiSaveData (new XMLData ()); business.SaveData (); .. } }
构造注入:
构造注入指在接受注入的类中定义一个构造方法,并在参数中定义需要注入的类。
为了让business类接受xmldata的注入,需要为它定义一个构造方法,来接受xmldata的注入。
public class Business { private SaveData db; public Business (SaveData db) { this.db = db; } .. //根据注入的存储类,存储数据 public void saveData () { .. db.saveData (); .. } }
编写TestBusiness.
public class TestBusiness { private Business business = new Business (new XMLData() ); .. //根据注入的存储类,存储数据 public void opraData () { .. business.saveData (); .. } }
spring提供了调用业务逻辑类的具体方式,开发人员不再需要编写调用具体业务逻辑的类,而是通过配置文档来实现对业务逻辑的调用。具体存储方式发生变化时,只需要改变相应的配置文档即可。
视图处理
Spring的视图处理方式有两个重要的接口: view resolver和view,view resolver提供了从视图名称到实际视图的映射,view用来处理请求的准备工作,并将该请求提交给某种具体的视图技术。
spring内置了三种视图方式,internalResourceView, JstlView, RedirectView。其中InternalResourceView用来处理tsp和servlet,jstlview用来处理jstle,redirect view用来处理重新定向视图。
所有的视图都继承了AbstarctUrlBasedView,只要继承AbstractUrlBasedView就能编写自己的视图。
解析器(都实现了viewResolver接口):
InternalResourceViewResolver解析器用来解析Servlet和JSP,
UrlBasedViewResolver 实现了ViewResolver,将视图名直接解析为对应的URL,不需要显式的映射定义。如果你的视图名和视图资源的名字一致,就可以使用该解析器,而无需进行映射,
AbstractCachingViewResolver 抽象视图解析器实现对视图的缓存,
XmlViewResolver 支持XML格式的配置文件,该配置文件必须采用Spring XML Bean Factory相同的DTD,默认配置文件是/WEB-INF/views.xml