其實
當為你的web應用程序創建一個構架時
這篇文章將討論怎樣組合幾個著名的框架去做到松耦合的目的
圖1用Struts
應用程序的分層 (Application Layering)
大多數不復雜的web應用都能被分成至少4個各負其責的層次
表現層 (The Presentation Layer)
在一個典型的web應用的一端是表現層
為用戶管理請求和響應
提供一個控制器(controller)代理調用業務邏輯和其它上層處理
處理從其它層擲出給一個Struts Action的異常
為顯示提供一個模型
執行用戶接口(UI)驗證
這兒是一些經常用Struts編寫的但是卻不應該和Struts表現層相伴的項目
直接和數據庫通訊
業務邏輯和與你的應用程序相關的驗證
事務管理
在表現層中引入這種代碼將導致典型耦合(type coupling)和討厭的維護
持久層 (The Persistence Layer )
在典型web應用的另一端是持久層
查詢相關的信息成為對象
保存
像Hibernate這樣的高級
這兒是一些應該在持久層裡被避免的項目
業務邏輯應該在你的應用的一個高一些的層次裡
你不應該把持久層邏輯(persistence logic)和你的表現層邏輯(presentation logic)攪在一起
業務層(The Business Layer)
在一個典型的web應用程序的中間的組件是業務層或服務層
這篇文章的後面將用例子來把Spring使用這些概念的方法說得更清楚一些
處理應用程序的業務邏輯和業務驗證
管理事務
預留和其它層交互的接口
管理業務層對象之間的依賴
增加在表現層和持久層之間的靈活性
從表現層中提供一個上下文(context)給業務層獲得業務服務(business services )
管理從業務邏輯到持久層的實現
領域模型層 (The Domain Model Layer )
最後
結合一個簡單的例子
既然我們已經從一個高的層次上理解了這些組件
你可以下載這個應用的源碼()
因為領域對象(domain objects)將和每一層交互
領域對象層(Domain Object Layer)
因為這些對象將和所有層交互
agle
agle
考慮一下為你的對象選擇包名
持久層配置(Persistence Layer Configuration)
用Hibernate設置持久層涉及到幾個步驟
Hibernate在XML文件裡映射領域對象到關系數據庫
Order
OrderLineItem
你可以在WebContent/WEB
業務層配置(Business Layer Configuration )
既然我們已經有了領域對象(domain objects)
這兒是個不使用IoC的對象創建它的從屬對象( object creating its dependencies without IoC)的例子
圖2
這兒是一個使用IoC的例子
圖3
建立我們的業務服務對象(Building Our Business Service Objects)
我們將在我們的業務對象中使用的setter方法接受的是接口
這兒是業務服務對象的接口
public interface IOrderService {
public abstract Order saveNewOrder(Order order)
throws OrderException
OrderMinimumAmountException;
public abstract List findOrderByUser(
String user)
throws OrderException;
public abstract Order findOrderById(int id)
throws OrderException;
public abstract void setOrderDAO(
IOrderDAO orderDAO);
}
注意上面的代碼有一個為DAO對象准備的setter方法
下一步是寫我們的DAO實現對象
orm/hibernate/support/Hibl)類
orm/hibernate/Hl)類的引用
public interface IOrderDAO {
public abstract Order findOrderById(
final int id);
public abstract List findOrdersPlaceByUser(
final String placedBy);
public abstract Order saveOrder(
final Order order);
}
我們還有兩個對象要和我們的業務層連在一起
orm/hibernate/HibernateTrl)
net.sf.hibernate.dialect.MySQLDialect false C:/MyWebApps/.../WEB-INF/proxool.xml spring
LocalSessionFactoryBean">
com/meagle/bo/Order.hbm.xml
com/meagle/bo/OrderLineItem.hbm.xml
springframework.
orm.
hibernate.
HibernateTransactionManager">
每一個對象能被Spring配置裡的一個
既然我們已經配置了我們的容器服務beans和把它們連在了一起,我們需要把我們的業務服務對象和我們的DAO對象連在一起。然後,我們需要把這些對象連接到事務管理器。
這是在Spring配置文件裡的樣子:
PROPAGATION_REQUIRED,readOnly,-OrderException PROPAGATION_REQUIRED,-OrderException
springframework.
transaction.
interceptor.
TransactionProxyFactoryBean">
meagle.
service.
spring.
OrderServiceSpringImpl">
meagle.
service.
dao.
hibernate.
OrderHibernateDAO">
圖4是我們已經連在一起的東西的一個概覽。它展示了每個對象是怎樣相關聯的和怎樣被Spring設置進其它對象中。把這幅圖和示例應用中的Spring配置文件對比查看它們之間的關系。
圖4:這是Spring怎樣將在這個配置的基礎上裝配beans。
這個例子使用一個TransactionProxyFactoryBean,它有一個為我們已經定義了的事務管理者准備的setter方法。這是一個有用的對象,它知道怎樣處理聲明的事務操作和你的服務對象。你可以通過transactionAttributes屬性定義事務怎樣被處理,transactionAttributes屬性為方法名定義模式和它們怎樣參與進一個事務。獲得更多的關於在一個事務上配置隔離層和提交或回滾查閱TransactionAttributeEditor(
transaction/interceptor/Transactiol)。
TransactionProxyFactoryBean(
transaction/interceptor/Transactionl)類也有一個為一個target准備的setter,target將是一個到我們的叫作orderTarget的業務服務對象的引用(a reference)。 orderTarget bean定義使用哪個業務服務對象並有一個指向setOrderDAO()的屬性。orderDAO bean將居於這個屬性中,orderDAO bean是我們的和持久層交流的DAO對象。
還有一個關於Spring和bean要注意的是bean能以兩種模式工作。這兩種模式被定義為singleton和prototype。一個bean默認的模式是singleton,意味著一個共享的bean的實例將被管理。這是用於無狀態操作--像一個無狀態會話bean將提供的那樣。當bean由Spring提供時,prototype模式允許創建bean的新實例。你應當只有在每一個用戶都需要他們自己的bean的拷貝時才使用prototype模式。
提供一個服務定位器(Providing a Service Locator)
既然我們已經把我們的服務和我們的DAO連起來了,我們需要把我們的服務暴露給其它層。通常是一個像使用Struts或Swing這樣的用戶接口層裡的代碼來使用這個服務。一個簡單的處理方法是使用一個服務定位器模式的類從一個Spring上下文中返回資源。這也可以靠引用bean ID通過Spring來直接完成。
這兒是一個在Struts Action中怎樣配置一個服務定位器的例子:
public abstract class BaseAction extends Action {
private IOrderService orderService;
public void setServlet(ActionServlet
actionServlet) {
super.setServlet(actionServlet);
ServletContext servletContext =
actionServlet.getServletContext();
WebApplicationContext wac =
WebApplicationContextUtils.
getRequiredWebApplicationContext(
servletContext);
this.orderService = (IOrderService)
wac.getBean("orderService");
}
protected IOrderService getOrderService() {
return orderService;
}
}
用戶接口層配置 (UI Layer Configuration)
示例應用的用戶接口層使用Struts框架。這兒我們將討論當為一個應用分層時和Struts相關的部分。
讓我們從在struts-config.xml文件裡檢查一個Action配置開始。
type="agle.action.SaveOrderAction"
name="OrderForm"
scope="request"
validate="true"
input="/NewOrder.jsp">
scope="request"
type="agle.exception.OrderException"/>
scope="request"
type="com.
meagle.
exception.
OrderMinimumAmountException"/>
SaveNewOrder Action被用來持久化一個用戶從用戶接口層提交的訂單。這是一個典型的Struts Action;然而,注意這個action的異常配置。這些Exceptions為我們的業務服務對象也在Spring 配置文件(applicationContext-hibernate.xml)中配置了(在transactionAttributes屬性裡)。當這些異常被從業務層擲出我們能在我們的用戶接口裡恰當的處理它們。第一個異常,OrderException,當在持久層裡保存訂單對象失敗時將被這個action使用。這將引起事務回滾和通過業務對象傳遞把異常傳回給Struts層。OrderMinimumAmountException,在業務對象邏輯裡的一個事務因為提交的訂單達不到最小訂單數量而失敗也將被處理。然後,事務將回滾和這個異常能被用戶接口層恰當的處理。
最後一個連接步驟是使我們的表現層和我們的業務層交互。這已經通過使用前面討論的服務定位器來完成了。服務層充當一個到我們的業務邏輯和持久層的接口。這兒是 Struts中的SaveNewOrder Action可能怎樣使用一個服務定位器調用一個業務方法:
public ActionForward execute(
ActionMapping mapping,
ActionForm form,
javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponse response)
throws java.lang.Exception {
OrderForm oForm = (OrderForm) form;
// Use the form to build an Order object that
// can be saved in the persistence layer.
// See the full source code in the sample app.
// Obtain the wired business service object
// from the service locator configuration
// in BaseAction.
// Delegate the save to the service layer and
// further upstream to save the Order object.
getOrderService().saveNewOrder(order);
oForm.setOrder(order);
ActionMessages messages = new ActionMessages();
messages.add(
ActionMessages.GLOBAL_MESSAGE,
new ActionMessage(
"message.order.saved.successfully"));
saveMessages(request, messages);
return mapping.findForward("success");
}
結論
這篇文章按照技術和架構覆蓋了許多話題。從中而取出的主要思想是怎樣更好的給你的應用程序分層:用戶接口層、持久邏輯層、和其它任何你需要的應用層。這樣可以解耦你的代碼,允許添加新的代碼組件,使你的應用在將來更易維護。這裡覆蓋的技術能很好的解決這類的問題。不管怎樣,使用這樣的構架可以讓你用其他技術代替現在的層。
From:http://tw.wingwit.com/Article/program/Java/ky/201311/28590.html