Springframework 是一個為了簡化JavaEE開發(fā)而創(chuàng)建的一個框架,其中主要的功能為IOC。簡單說明參看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的來源
時代的變遷:
New → 基于接口的編程 → 工廠方法 → Ioc
我們先看一個代碼關(guān)系,例如:
TopLogic需要一個SecondLogic完成一定的業(yè)務(wù)。
SecondLogic需要TopDAO來完成數(shù)據(jù)庫訪問。
New時代:
那么一定會有這樣的代碼:
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時代,對象間的關(guān)系通過New操作符鏈接,如果你需要一個對象,簡單的New一個就好。
New的好處是非常簡單,不好的地方有兩點,第一,你不知道New了多少個,在哪里New的。
第二是,一旦對象的名字發(fā)生了變更,或者New的初始化發(fā)生了變更(更常見),所有使用到New的地方都需要修改。
基于接口的時代:
接口是服務(wù)定義,接口是類型定義:一個接口定義了一種類型(接口名字),這種類型提供
特定的服務(wù)(接口方法)。
基于接口的編程一定要講一個服務(wù)類(例如TopLogic,SecondLogic等)分成兩部分,一個用于定義服務(wù)的接口,和
一個實現(xiàn)了接口方法的實現(xiàn)類。
例如
public interface SecondLogic {
public void someMethod();
}
public class SecondLogicImpl implements SecondLogic{
public void someMethod() {
....
}
}
在TopLogic中使用SecondLogic的時候,不需要使用SecondLogicImpl定義,而用接口定義,
只是在實例化這個類型(接口)的時候才需要實例化類的名字(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)生了工廠方法
例如,我們會有SecondLogicFacotry工廠負(fù)責(zé)專門初始化SecondLogic的實例,代碼為:
public class SecondLogicFactory {public static SecondLogic createSecondLogic() {
SecondLogic logic = new SecondLogicImpl();
//以下為初始化方法調(diào)用
logic.XXX
...
return logic;}
}
public class TopLogic{
private SecondLogic logic ;
public TopLogic() {
logic = SecondLogicFactory.createSecondLogic()
}
public topMethod() {
loggic.someMethod();
}
}
通常上述逐步的簡化代碼變得越來越清楚。
在TopLogic中聲明存儲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的時候,其中的secondLogic屬性自動的通過
配置文件的配置得到了初始化。
為什么Strut2需要使用SpringFramework
在Struts2中Action是我們擴展的點,我們使用Action處理用戶提交的請求,向用戶展現(xiàn)數(shù)據(jù)。
為了更好的組織代碼的結(jié)構(gòu),我們一般情況下使用三層的構(gòu)架:
Action → Logic → Dao
這樣如果我們手動的管理這些對象之間的關(guān)系,以方便非常的繁瑣,另外也很不利于管理
變更,所以我們更傾向于使用Spring等類似的IOC框架類管理。
如何將Springframework和Struts2結(jié)合起來
回想第一章,我們指導(dǎo)在Struts2中每一個對象都是靠ObjectFactory創(chuàng)建的,而Springframework
就是用來管理對象創(chuàng)佳的,我們只需要將ObjectFactory的對象創(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模塊,實際項目中可以考慮使用具體的模塊)
3)剩余的就是Springframework的配置了
第一,告訴Spring,對象間關(guān)系的配置在那里存放
需要在web.xml文件中添加如下內(nèi)容(注意順序):
這個Listener在應(yīng)用程序啟動的時候啟動,用來讀取配置文件。
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
這個參數(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會根據(jù)struts.xml中配置的class名字在springframeowrk中找id相同的bean,如果找不到
就按照普通的方式實例化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會使用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)容,請參看www.springframework.org
ExtJS教程- Hibernate教程-Struts2 教程-Lucene教程