Springframework 是一個(gè)為了簡(jiǎn)化JavaEE開發(fā)而創(chuàng)建的一個(gè)框架,其中主要的功能為IOC。簡(jiǎn)單說明參看Springfremework founder Rod Johnson 寫的

Introduction to Springframwork

http://www.theserverside.com/tt/articles/article.tss?l=SpringFramework

 

Sringframework總最著名的特性要數(shù)控制反轉(zhuǎn)(Inversion of Control),也叫依賴注入(Dependency Injection),詳細(xì)參看Martin Flower的文章:

Inversion of Control Containers and the Dependency Injection pattern

http://martinfowler.com/articles/injection.html

 

Ioc的來源


時(shí)代的變遷:

New 基于接口的編程 工廠方法 Ioc


我們先看一個(gè)代碼關(guān)系,例如:

TopLogic需要一個(gè)SecondLogic完成一定的業(yè)務(wù)。

SecondLogic需要TopDAO來完成數(shù)據(jù)庫訪問。


New時(shí)代:

那么一定會(huì)有這樣的代碼:

public class TopLogic{

    private SecondLogic logic ;


    public TopLogic() {

       logic = new SecondLogic();

       //以下為初始化方法調(diào)用

       logic.XXX

       ...

    }  


    public topMethod() {

       loggic.someMethod();

    }


}


public class SecondLogic{

    private TopDAO dao ;


    public SecondLogic() {

       dao = new TopDAO();

       //以下為初始化方法調(diào)用

       dao.XXX

       ...

    }  

}


在New時(shí)代,對(duì)象間的關(guān)系通過New操作符鏈接,如果你需要一個(gè)對(duì)象,簡(jiǎn)單的New一個(gè)就好。
New的好處是非常簡(jiǎn)單,不好的地方有兩點(diǎn),第一,你不知道New了多少個(gè),在哪里New的。
第二是,一旦對(duì)象的名字發(fā)生了變更,或者New的初始化發(fā)生了變更(更常見),所有使用到New的地方都需要修改。

基于接口的時(shí)代:
接口是服務(wù)定義,接口是類型定義:一個(gè)接口定義了一種類型(接口名字),這種類型提供
特定的服務(wù)(接口方法)。

基于接口的編程一定要講一個(gè)服務(wù)類(例如TopLogic,SecondLogic等)分成兩部分,一個(gè)用于定義服務(wù)的接口,和
一個(gè)實(shí)現(xiàn)了接口方法的實(shí)現(xiàn)類。
例如
public interface SecondLogic {
    public void someMethod();
}

public class SecondLogicImpl implements SecondLogic{
    public void someMethod() {
       ....
    }
}

在TopLogic中使用SecondLogic的時(shí)候,不需要使用SecondLogicImpl定義,而用接口定義,
只是在實(shí)例化這個(gè)類型(接口)的時(shí)候才需要實(shí)例化類的名字(SecondLogicImpl)例如:


public class TopLogic{

    private SecondLogic logic ;


    public TopLogic() {

       logic = new SecondLogicImpl();

       //以下為初始化方法調(diào)用

       logic.XXX

       ...

    }  


    public topMethod() {

       loggic.someMethod();

    }


}

通過使用基于接口的編程,減低了變量名字變更造成的影線,但是沒有降低變量初始化
過程變化的影響。

工廠方法和基于接口聯(lián)合使用
為了將變量初始化過程變化的影響變?yōu)樽钚。仨毎炎兞康某跏蓟椒L(fēng)中起來,于是
產(chǎn)生了工廠方法

例如,我們會(huì)有SecondLogicFacotry工廠負(fù)責(zé)專門初始化SecondLogic的實(shí)例,代碼為:

public class SecondLogicFactory {
    public static SecondLogic createSecondLogic() {
       SecondLogic logic = new SecondLogicImpl();

       //以下為初始化方法調(diào)用

       logic.XXX

       ...

       return logic;
    }
}


這時(shí),TopLogic中所有關(guān)于SecondLogic初始化的內(nèi)容都被移除了,TopLogic變?yōu)椋?br />

public class TopLogic{

    private SecondLogic logic ;


    public TopLogic() {

       logic = SecondLogicFactory.createSecondLogic()

    }  


    public topMethod() {

       loggic.someMethod();

    }


}


通常上述逐步的簡(jiǎn)化代碼變得越來越清楚。


Ioc時(shí)代(以Spring為例)

 

Ioc將所有的對(duì)象之間的關(guān)系轉(zhuǎn)移到了xml配置文件中來。
在TopLogic中聲明存儲(chǔ)SecondLogic的屬性

public class TopLogic{

    private SecondLogic logic ;


    public void setSecondLogic(SecondLogic logic) {
       this.logic = logic;
    }

    public TopLogic() {


    }  


    public topMethod() {

       loggic.someMethod();

    }


}


聲明變量之間的關(guān)系:

<beans>
    <bean id="secondLogic" class="com.jpleasure.teamware.logic.SecondLogic">
       <property name="XXX" value = "11111"/>
       <property name="YYY" value = "22222"/>
    </bean>
    <bean id="topLogic" class="com.jpleasure.teamware.logic.TopLogic">
       <property name="secondLogic" ref = "secondLogic"/>
    </bean>
</beans>

當(dāng)我們從Spring IOC容器中取得topLogic的時(shí)候,其中的secondLogic屬性自動(dòng)的通過
配置文件的配置得到了初始化。

為什么Strut2需要使用SpringFramework
在Struts2中Action是我們擴(kuò)展的點(diǎn),我們使用Action處理用戶提交的請(qǐng)求,向用戶展現(xiàn)數(shù)據(jù)。
為了更好的組織代碼的結(jié)構(gòu),我們一般情況下使用三層的構(gòu)架:
Action → Logic → Dao
這樣如果我們手動(dòng)的管理這些對(duì)象之間的關(guān)系,以方便非常的繁瑣,另外也很不利于管理
變更,所以我們更傾向于使用Spring等類似的IOC框架類管理。

如何將Springframework和Struts2結(jié)合起來
回想第一章,我們指導(dǎo)在Struts2中每一個(gè)對(duì)象都是靠ObjectFactory創(chuàng)建的,而Springframework
就是用來管理對(duì)象創(chuàng)佳的,我們只需要將ObjectFactory的對(duì)象創(chuàng)建方法改為Spring即可。

1)在struts.properties或者struts.xml文件中將objectfactory的屬性設(shè)置為spring方式:
    xml方式:
    <constant name="struts.objectFactory" value="org.apache.struts2.spring.StrutsSpringObjectFactory" />
    properties方式:
    struts.objectFactory=org.apache.struts2.spring.StrutsSpringObjectFactory
2)當(dāng)然還需要將需要的Jar文件放在WEB-INF/lib目錄下
    這些文件包括:
    struts2-spring-plugin-2.0.9.jar
    spring.jar(為了省事,包含了所有的spring模塊,實(shí)際項(xiàng)目中可以考慮使用具體的模塊)
3)剩余的就是Springframework的配置了
    第一,告訴Spring,對(duì)象間關(guān)系的配置在那里存放
    需要在web.xml文件中添加如下內(nèi)容(注意順序):
    這個(gè)Listener在應(yīng)用程序啟動(dòng)的時(shí)候啟動(dòng),用來讀取配置文件。
    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>

    這個(gè)參數(shù)配置了配置文件的路徑,說明我們可以在classpath或者WEB-INF目錄下
    防止名字滿足applicationContext-*.xml格式你的文件。
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/applicationContext-*.xml,classpath*:applicationContext-*.xml
        </param-value>
    </context-param>

4)如何讓Struts2的Action和Springframework的bean管理起來?
    Struts2會(huì)根據(jù)struts.xml中配置的class名字在springframeowrk中找id相同的bean,如果找不到
    就按照普通的方式實(shí)例化Action類。
    例如:
    struts-todo.xml
        <action name="forward" method="forward"
            class="todo">
            <result name="insert">/todo/insert.jsp</result>
            <result name="update">/todo/insert.jsp</result>
            <result name="delete">/todo/insert.jsp</result>
        </action>
    applicationContext-todo.xml
        <bean id="todo" class="com.jpleasure.teamware.action.TodoAction"
            singleton="false">
        <property name="todoLogic" ref="todoLogic"></property>
        </bean>
    則class=“todo”的Action會(huì)使用com.jpleasure.teamware.action.TodoAction。

基本程序結(jié)構(gòu):
│  .classpath
│  .project
├─src
│  │  applicationContext-todo.xml
│  │  struts-todo.xml
│  │  struts.properties
│  │  struts.xml
│  │  teamware.properties
│  │ 
│  └─com
│      └─jpleasure
│          └─teamware
│              ├─action
│              ├─dao
│              ├─fw
│              ├─logic
│              ├─util
│              └─vo
└─WebContent
    │  Index.html
    │  Index.jsp
    │ 
    ├─META-INF
    │      MANIFEST.MF
    │     
    ├─todo
    │      list.jsp
    │     
    └─WEB-INF
        │  web.xml
        │ 
        └─lib
                commons-logging-1.0.4.jar
                freemarker-2.3.8.jar
                ognl-2.6.11.jar
                spring.jar
                struts2-core-2.0.9.jar
                struts2-spring-plugin-2.0.9.jar
                xwork-2.0.4.jar
               

關(guān)于Spring的內(nèi)容,請(qǐng)參看www.springframework.org

ExtJS教程- Hibernate教程-Struts2 教程-Lucene教程