续前,现在我们来看看 Spring 的配置文件 applicationContext-hibernate.xml :
<beans>
<!-- 数据源定义-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName"><value>com.mysql.jdbc.Driver</value></property>
<property name="url"><value>jdbc:mysql://localhost:3306/test</value></property>
<property name="username"><value>root</value></property>
<property name="password"><value></value></property>
</bean>
<!-- Hibernate 的 SessionFactory 定义 -->
<bean id="mySessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource"><ref local="dataSource"/></property>
<property name="mappingResources">
<list>
<value>com/meagle/bo/Order.hbm.xml</value>
<value>com/meagle/bo/OrderLineItem.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<!-- 对单一 Hibernate SessionFactory 的事务管理器定义 -->
<bean id="myTransactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory"><ref local="mySessionFactory"/></property>
</bean>
<!-- 业务服务对象定义 并将它配置在事务管理器中 -->
<bean id="orderService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager"><ref local="myTransactionManager"/></property>
<property name="target"><ref local="orderTarget"/></property>
<property name="transactionAttributes">
<props>
<prop key="find*">PROPAGATION_REQUIRED,readOnly,-OrderException</prop>
<prop key="save*">PROPAGATION_REQUIRED,-OrderException,-OrderMinimumAmountException</prop>
</props>
</property>
</bean>
<!-- 业务对象实现定义 -->
<bean id="orderTarget" class="com.meagle.service.spring.OrderServiceSpringImpl">
<property name="orderDAO"><ref local="orderDAO"/></property>
</bean>
<!-- Hibernate 实现的 DAO 对象定义 -->
<bean id="orderDAO" class="com.meagle.service.dao.hibernate.OrderHibernateDAO">
<property name="sessionFactory"><ref local="mySessionFactory"/></property>
</bean>
</beans>
这里我们使用了 Spring 提供的便捷的方式-----在 Spring 内部配置中并入了 Hibernate 的配置。也可以在 Spring 外使用 Hibernate,将 Hibernate 的配置写在 hibernate.cfg.xml 中。
从下图可以看出,每个对象都联系着 Spring,并且能通过 Spring 注入到其他对象。把它与 Spring 的配置文件比较,观察他们之间的关系:
4. 既然已经将各种服务对象搭配起来了,现在需要把服务显示到其他层。 这个通常是在 Struts 或者 Swing 这层里编码。一个简单方法就是用服务定位器返回给 Spring context 。当然,可以通过直接调用 Spring 中的Bean 来做。
下面就是一个 Struts Action 中的服务定位器使用的例子(后面的 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;
}
}
既然表示层是使用 Struts 框架的,现在来看看 Struts 的配置文件是怎样的:
<struts-config>
<!-- Form Beans -->
<form-beans>
<form-bean name="OrderForm" type="com.meagle.forms.OrderForm"/>
</form-beans>
<!-- Global Exceptions -->
<global-exceptions>
<exception key="global.data.access.exception"
path="/queryOrder.jsp"
scope="request"
type="org.springframework.dao.DataAccessException"/>
</global-exceptions>
<!-- Action Mappings -->
<action-mappings>
<action path="/Index"
forward="/index.jsp"/>
<action path="/PlaceOrder"
forward="/newOrder.jsp"/>
<action path="/QueryOrder"
forward="/queryOrder.jsp"/>
<action path="/SaveNewOrder"
type="com.meagle.action.SaveOrderAction"
name="OrderForm"
scope="request"
validate="true"
input="/newOrder.jsp">
<display-name>Save New Order</display-name>
<exception key="error.order.save"
path="/newOrder.jsp"
scope="request"
type="com.meagle.exception.OrderException"/>
<exception key="error.order.not.enough.money"
path="/newOrder.jsp"
scope="request"
type="com.meagle.exception.OrderMinimumAmountException"/>
<forward name="success" path="/viewOrder.jsp"/>
<forward name="failure" path="/newOrder.jsp"/>
</action>
<action path="/FindOrderID"
type="com.meagle.action.FindOrderAction"
name="OrderForm"
scope="request"
validate="true"
input="/queryOrder.jsp">
<display-name>Find Existing Order</display-name>
<exception key="error.order.find"
path="/queryOrder.jsp"
scope="request"
type="com.meagle.exception.OrderException"/>
<forward name="success" path="/viewOrder.jsp"/>
</action>
</action-mappings>
<message-resources parameter="com.meagle.resources.ApplicationResources"/>
</struts-config>
SaveNewOrder 这个 Action 是处理表示层里提交的表单。这是 Struts 中很典型的 Action。注意观察它的 exception 配置,这些 Exceptions 也在 Spring 配置文件中配置了。 当异常在业务层被被抛出时,我们可以控制他们,并适当的显示到表示层。OrderException 在持久层保存 order 对象失败的时候被触发。这将导致事物回滚并且通过业务对象把异常回传到 Struts 这一层。OrderMinimumAmountException 也是一样。
这两个 Action 类都继承了前面提到 BaseAction,现在看看 SaveNewAction 这个类中与业务层的交互:
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;
Order order = new Order();
order.setUserName(oForm.getWhoPlacedOrder());
Set lineItems = new HashSet();
if (oForm.getItemDesc_1() != null && oForm.getItemDesc_1().length() > 0) {
OrderLineItem item = new OrderLineItem();
item.setDescription(oForm.getItemDesc_1());
item.setLineItemPrice(oForm.getItemPrice_1());
lineItems.add(item);
item.setOrder(order);
}
if (oForm.getItemDesc_2() != null && oForm.getItemDesc_2().length() > 0) {
OrderLineItem item = new OrderLineItem();
item.setDescription(oForm.getItemDesc_2());
item.setLineItemPrice(oForm.getItemPrice_2());
lineItems.add(item);
item.setOrder(order);
}
if (oForm.getItemDesc_3() != null && oForm.getItemDesc_3().length() > 0) {
OrderLineItem item = new OrderLineItem();
item.setDescription(oForm.getItemDesc_3());
item.setLineItemPrice(oForm.getItemPrice_3());
lineItems.add(item);
item.setOrder(order);
}
order.setOrderLineItems(lineItems);
getOrderService().saveNewOrder(order);
oForm.setOrder(order);
ActionMessages messages = new ActionMessages();
messages.add(Globals.MESSAGE_KEY, new ActionMessage("message.order.saved.successfully"));
saveErrors(request, messages);
return mapping.findForward("success");
}
说到这差不多了。在 web.xml 中需要引入 Spring 的配置文件。可以参考我前面的文章。
如果有需要示例的全部代码,请告诉我邮箱。