(转帖)Wiring Your Web Application with Open Source Java(2)

(由admin转自:http://www.onjava.com/pub/a/onjava/2004/04/07/wiringwebapps.html?page=2)

[译者注:欢迎大家直接在这篇译文中修改和完善,并留下你的联系方式。]

 

Wiring Together a Simple Example

Now that we understand the components from a high level, let's put this into practice. Again, for this example, we will combine the Struts, Spring, and Hibernate frameworks. Each one of these frameworks has too much detail to cover in one article. Instead of going into many details about each framework, this article will show how to wire them together with simple example code. The sample application will demonstrate how a request is serviced across each layer. A user of this sample application can save a new order to the database and view an existing order in the database. Further enhancements might allow the user to update or delete an existing order.

结合一个简单的例子

  现在,我们从一个高的层次理解了组件,让我们把这些用于实践。在这个例子中,我们将合并Struts、Spring、Hibernate框架。每一个这些框架在一篇文章中都有太多的细节覆盖到。这篇文章将用一个简单的例子代码展示怎样把它们结合在一起,而不是进入每个框架的许多细节。示例应用将示范一个请求怎样跨越每一层被服务。这个示例应用的一个用户能保存一个订单到数据库中和查看一个在数据库中存在的订单。进一步的提高也许允许用户更新或删除一个存在的订单。  

 

You can download the source code of the application.

你可以下载这个应用的源码。

First, we will create our domain objects since they will interoperate with each layer. These objects will allow us to define what should be persisted, what business logic should be provided, and what type of presentation interface should be designed. Next, we will configure the persistence layer and define object-to-relational mappings with Hibernate for our domain objects. Then we will define and configure our business objects. After we have these components we can discuss wiring these layers using Spring. Finally, we will provide a presentation layer that knows how to communicate with the business service layer and knows how to handle exceptions that arise from other layers.

  首先,我们将创建我们的领域对象因为它们将和每一层交互。这些对象将允许我们定义什么应该被持久化,什么业务逻辑应该被提供,和哪种表现界面应该被设计。然后,我们将配置持久层和为我们的领域对象用Hibernate定义“对象-关系”映射。然后,我们将定义和配置我们的业务对象。在有了这些组件后,我们能讨论和Spring把这些层连在一起。最后,我们将提供一个表现层,它知道怎样和业务服务层交流和知道怎样处理从其它层产生的异常。

Domain Object Layer

Since these objects will interoperate across all layers this might be a good place to start coding. This simple domain model will contain an object that represents an order and an object that represents a line item for an order. The order object will have a one-to-many relationship to a collection of line item objects. The example code has two simple objects in the domain layer:

com.meagle.bo.Order.java: contains the header-level information for an order.

com.meagle.bo.OrderLineItem.java: contains the detail-level information for an order.

Consider choosing package names for your objects that reflect how your application is layered. For example, the domain objects in the sample application can be located in the com.meagle.bo package. More specialized domain objects would be located in subpackages under the com.meagle.bo package. The business logic begins in the com.meagle.service package and DAO objects are located in the com.meagle.service.dao.hibernate package. The presentation classes for forms and actions reside in com.meagle.action and com.meagle.forms, respectively. Accurate package naming provides a clear separation for the functionality that your classes provide, allows for easier maintenance when troubleshooting, and provides consistency when adding new classes or packages to the application.

领域对象层

因为这些对象将和所有层交互,这也许是一个开始编码的好地方。这个简单的领域模型将包括一个代表一份订单的对象和一个代表一个订单项的对象。订单对象将和一组订单项对象有一对多的关系。例子代码在领域层有两个简单的对象:

com.meagle.bo.Order.java: 包括一份订单的概括信息;

com.meagle.bo.OrderLineItem.java: 包括一份订单的详细信息;

考虑为你的对象选择包名,它将反映你的应用是怎样分层的。例如:简单应用的领域对象可以放进com.meagle.bo包[译者注:bo-business object?]。更多专门的领域对象将放入在com.meagle.bo下面的子包里。业务逻辑在com.meagle.service包里开始,DAO对象被放进com.meagle.service.dao.hibernate包。对于forms和actions的表现类分别驻入com.meagle.action 和 com.meagle.forms包。准确的包命名为你的类提供的功能提供一个清楚的区分,考虑到当故障维护时更易于维护,当增加新的类或包给应用时提供一致性。

Persistence Layer Configuration

There are several steps involved in setting up the persistence layer with Hibernate. The first step is to configure our domain business objects to be persisted. Since Hibernate works with POJOs we will use our domain objects for persistence. Therefore the Order and OrderLineItem objects will need to provide getter and setter methods for all fields that they contain. The Order object would contain setter and getter methods such as ID, UserName, Total, and OrderLineItems in a standard JavaBean format. The OrderLineItem would similarly follow the JavaBean format for its fields.

Hibernate maps domain objects-to-relational databases in XML files. For our Order and OrderLineItem objects there will be two mapping files to express this. There are tools such as XDoclet to assist with this mapping. Hibernate will map the domain objects to these files:

Order.hbm.xml

OrderLineItem.hbm.xml

You will find these generated files in the WebContent/WEB-INF/classes/com/meagle/bo directory. The Hibernate SessionFactory is configured to know which database it is communicating with, the DataSource or connection pool to use, and what persistent objects are available for persistence. Session objects provided by the SessionFactory are the interface used to translate between Java objects and persistence functions such as selecting, saving, updating, and deleting objects. We will discuss configuring the SessionFactory that Hibernate requires to handle Session objects in a later section.

持久层配置

用Hibernate设置持久层涉及到几个步骤。第一步是配置我们的被持久化的领域对象。因为Hibernate和POJOs[译者注:Persistence Objects Java Objects?]一起工作,我们将使用我们的领域对象持久化。因此,订单和订单项对象将需要提供它们包括的所有的字段的getter和setter方法。订单对象将包括像ID、用户名、合计、和订单项这样一些字段的以一种标准的JavaBean的格式的setter和getter方法。订单项对象将同样的用JavaBean的格式为它的字段设置setter和getter方法。

  Hibernate在XML文件里映射领域对象到关系数据库。为我们的订单和订单项对象将有两个映射文件来表达这种映射。有像XDoclet这样的工具来帮助这种映射。Hibernate将映射领域对象到这些文件:

Order.hbm.xml

OrderLineItem.hbm.xml

你可以在WebContent/WEB-INF/classes/com/meagle/bo目录里找到这些生成的文件。Hibernate SessionFactory被配置来知道它正和哪种数据库交流、使用哪种数据源或连接池、什么持久的对象被持久化是有效的。被SessionFactory提供的Session对象是用于在Java对象和像选取、保存、更新、删除对象这样的一些持久化功能间的翻译的接口。我们将在后面的小节讨论配置Hibernate处理Session对象需要的SessionFactory。

Business Layer Configuration

Now that we have our domain objects we need to have business service objects that perform application logic, make calls to the persistence layer, take requests from the UI layer, deal with transactions, and handle exceptions. To wire all of this together and make this easy to manage we will use the bean management aspect of the Spring framework. Spring uses inversion of control (IoC), or setter dependency injection, to wire up objects that are referenced in an external XML file. Inversion of control is a simple concept that allows objects to accept other objects that are created at a higher level. This way your object is free from having to create objects and reduces object coupling.

Here is an example of an object creating its dependencies without IoC, which leads to tight object coupling:

Figure 2. Objects arranged without IoC. Object A creates objects B and C.

And here is an example with IoC that allows objects to be created at higher levels and passed into objects so that they can use the implementations directly:

Figure 3. Objects arranged with IoC. Object A contains setter methods that accept interfaces to objects B and C. This could have also been achieved with constructors in object A that accepts objects B and C.

业务层配置

  现在,我们有了我们的领域对象,我们需要有业务服务对象来执行应用逻辑、执行向持久层的调用、获得从用户界面层的请求、处理事务、处理异常。为了把所有这些连在一起使它易于管理,我们将使用Spring框架的bean管理方面的功能。Spring使用“控制反转”(IoC),或者“setter依赖注入”来把这些对象连好,这些对象在一个外部的XML文件中被引用。“控制反转”是一个简单的概念,它允许对象接受其它在一个高一些的层次创建的对象。使用这种方法,你的对象从必须创建其它对象中解放出来和减少对象耦合。

  这儿是个不使用IoC的对象创建它的从属对象的例子,这导致紧的对象耦合:

  图2:没有使用IoC的对象组织。对象A创建对象B和C。

  这儿是一个使用IoC的例子,它允许对象在一个高一些层次被创建和传进对象,所以它们能直接使用现存的对象:

  图3:对象使用IoC组织。对象A包含setter方法,它们接受到对象B和C的接口。这也可以用对象A里的接受对象B和C的构建器完成。

Building Our Business Service Objects

The setters we will use in our business objects accept interfaces that allow loosely defined implementations of the objects that will be set, or injected. In our case we will allow our business service object to accept a DAO to handle the persistence of our domain objects. While the examples in this article use Hibernate, we can easily switch implementations to a different persistence framework and inform Spring of the new implementation DAO object to use. You can see how programming to interfaces and using the dependency injection pattern loosely couples your business logic from your persistence mechanism.

Here is the interface for the business service object that is stubbed for a DAO object dependency:

建造我们的业务服务对象

  我们将在我们的业务对象中使用的setter方法接受接口,这些接口允许将被设置或者注入的对象的宽松实现。在我们这个例子里我们将允许我们的业务服务对象接受一个DAO去控制我们的领域对象的持久化。虽然在这篇文章的例子中使用Hibernate,我们可以容易的转换到一个不同的持久框架的实现,通知Spring使用新的实现的DAO对象。你将看见怎样编程到接口和使用“依赖注入”模式宽松耦合你的业务逻辑和你的持久化机制。

  这儿是业务服务对象的接口,它有一个DAO对象依赖的桩。[译者注:是setOrderDAO方法吗?]

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);

}

Notice that the code above has a setter for a DAO object. There is not a getOrderDAO method because it is not necessary since there is often no need to access the wired OrderDAO object from the outside. The DAO object will be used to communicate with our persistence layer. We will wire the business service object and the DAO object together with Spring. Because we are coding to interfaces, we do not tightly couple the implementation.

  注意上面的代码有一个为DAO对象准备的setter方法。这儿不是一个getOrderDAO方法因为它不是必要的,因为不太有从外面访问连着的OrderDAO对象的需要。DAO对象将被用来和我们的持久层沟通。我们将用Spring把业务服务对象和DAO对象连在一起。因为我们编码到接口,我们不会紧耦合实现。

The next step is to code our DAO implementation object. Since Spring has built-in support for Hibernate this example DAO will extend the HibernateDaoSupport class, which allows us to easily get a reference to a HibernateTemplate, which is a helper class that simplifies coding with a Hibernate Session and handles HibernateExceptions. Here is the interface for the DAO:

下一步是写我们的DAO实现对象。因为Spring有Hibernate内建的支持,这个例子DAO将继承HibernateDaoSupport类,它[译者注:英语语法问题:它是指“例子DAO”还是指“HibernateDaoSupport类”?]允许我们容易取得一个到HibernateTemplate的引用,HibernateTemplate是一个帮助类,它能简化Hibernate Session的编码和处理HibernateExceptions。这儿是DAO的接口:

public interface IOrderDAO {

  public abstract Order findOrderById(

                                    final int id);

  public abstract List findOrdersPlaceByUser(

                           final String placedBy);

  public abstract Order saveOrder(

                               final Order order);

}

We still have a couple more objects to wire together for our business layer. This includes the HibernateSessionFactory and a TransactionManager object. This is done directly in the Spring configuration file. Spring provides a HibernateTransactionManager, which will bind a Hibernate Session from the factory to a thread to support transactions (see ThreadLocal for more information). Here is the Spring configuration of the HibernateSessionFactory and the HibernateTransactionManager:

  我们还有两个对象要和我们的业务层连在一起。这包括HibernateSessionFactory和一个TransactionManager对象。这在Spring配置文件里直接完成。Spring提供一个HibernateTransactionManager,它将从工厂绑定一个Hibernate Session到一个线程来支持事务(见ThreadLocal获取更多的信息)。这儿是HibernateSessionFactory和HibernateTransactionManager的Spring配置。

<bean id="mySessionFactory"

       class="org.springframework.orm.hibernate.

              LocalSessionFactoryBean">

  <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">

        net.sf.hibernate.dialect.MySQLDialect

      </prop>

      <prop key="hibernate.show_sql">

        false

      </prop>

      <prop key="hibernate.proxool.xml">

        C:/MyWebApps/.../WEB-INF/proxool.xml

      </prop>

      <prop key="hibernate.proxool.pool_alias">

          spring

      </prop>

    </props>

  </property>

</bean>

<!-- Transaction manager for a single Hibernate

SessionFactory (alternative to JTA) -->

<bean id="myTransactionManager"

         class="org.

                springframework.

                orm.

                hibernate.

                HibernateTransactionManager">

  <property name="sessionFactory">

    <ref local="mySessionFactory"/>

  </property>

  </bean>

Each object can be referenced in the Spring configuration within a <bean> tag. In this case the bean mySessionFactory represents a HibernateSessionFactory and the bean myTransactionManager represents a Hibernate transaction manager. Notice that the transactionManger bean has a property element called sessionFactory. The HibernateTransactionManager class has a setter and getter for sessionFactory, which is used for dependency injection when the Spring container starts. The sessionFactory property references the mySessionFactory bean. These two objects will now be wired together when the Spring container initializes. This wiring relieves you from creating singleton objects and factories for referencing and creating these objects, which reduces code maintenance in your application. The mySessionFactory bean has two property elements, which translate to setters for mappingResources and hibernatePropertes. Normally, this configuration would be stored in the hibernate.cfg.xml file if you were using Hibernate outside of Spring. However, Spring provides an easy way to incorporate the Hibernate configuration within the Spring configuration file. For more information see the Spring API.

 

  每一个对象能被Spring配置里的一个<bean>标记引用。在这个例子里,bean “mySessionFactory”代表一个HibernateSessionFactory,bean “myTransactionManager”代表一个Hibernate transaction manager。注意transactionManger bean有一个叫作sessionFactory的属性元素。HibernateTransactionManager有一个为sessionFactory准备的setter和getter方法,它们是用来当Spring容器启动时的依赖注入。sessionFactory属性指的是mySessionFactory bean。这两个对象现在当Spring容器初始化时将被连在一起。这种连接把你从为引用和创建这些对象而创建singleton对象和工厂中解放出来,这减少了你的应用中的代码维护。mySessionFactory bean有两个属性元素,它们转换到为mappingResources 和 hibernatePropertes的setter方法。通常,如果你在Spring外面使用Hibernate,这个配置将被保存在hibernate.cfg.xml文件中。然而,Spring提供一个容易的方法在Spring配置文件内合并Hibernate配置。获得更多的信息看Spring API.

[注:由admin翻译上述部分2005年12月31日17:45分;由***在***修改了上述部分;由***在***修改了上述部分...请自行填写,以便联系] 

Author: test

供游客使用的测试帐号

One thought on “(转帖)Wiring Your Web Application with Open Source Java(2)”

  1. (为预防误操作,特此备份。因为学习日记的session设置为20分钟如果没有动作就会清除当前用户连接信息,要求重新登录。因此,你超过20分钟没有保存的东西就有可能丢失,所以写东西请20分钟内保存一次)

     日记标题 (转帖)Wiring Your Web Application with Open Source Java(2)  作者: guest  创建时间: 2005-12-28 20:58:18  最近更新: 2005-12-31 17:45:14  编辑 我要评论  

    内容

    (由admin转自:http://www.onjava.com/pub/a/onjava/2004/04/07/wiringwebapps.html?page=2)

    Wiring Together a Simple Example

    Now that we understand the components from a high level, let's put this into practice. Again, for this example, we will combine the Struts, Spring, and Hibernate frameworks. Each one of these frameworks has too much detail to cover in one article. Instead of going into many details about each framework, this article will show how to wire them together with simple example code. The sample application will demonstrate how a request is serviced across each layer. A user of this sample application can save a new order to the database and view an existing order in the database. Further enhancements might allow the user to update or delete an existing order.

    结合一个简单的例子

      现在,我们从一个高的层次理解了组件,让我们把这些用于实践。在这个例子中,我们将合并Struts、Spring、Hibernate框架。每一个这些框架在一篇文章中都有太多的细节覆盖到。这篇文章将用一个简单的例子代码展示怎样把它们结合在一起,而不是进入每个框架的许多细节。示例应用将示范一个请求怎样跨越每一层被服务。这个示例应用的一个用户能保存一个订单到数据库中和查看一个在数据库中存在的订单。进一步的提高也许允许用户更新或删除一个存在的订单。  

      

    You can download the source code of the application.

    你可以下载这个应用的源码。

    First, we will create our domain objects since they will interoperate with each layer. These objects will allow us to define what should be persisted, what business logic should be provided, and what type of presentation interface should be designed. Next, we will configure the persistence layer and define object-to-relational mappings with Hibernate for our domain objects. Then we will define and configure our business objects. After we have these components we can discuss wiring these layers using Spring. Finally, we will provide a presentation layer that knows how to communicate with the business service layer and knows how to handle exceptions that arise from other layers.

      首先,我们将创建我们的领域对象因为它们将和每一层交互。这些对象将允许我们定义什么应该被持久化,什么业务逻辑应该被提供,和哪种表现界面应该被设计。然后,我们将配置持久层和为我们的领域对象用Hibernate定义“对象-关系”映射。然后,我们将定义和配置我们的业务对象。在有了这些组件后,我们能讨论和Spring把这些层连在一起。最后,我们将提供一个表现层,它知道怎样和业务服务层交流和知道怎样处理从其它层产生的异常。

    Domain Object Layer

    Since these objects will interoperate across all layers this might be a good place to start coding. This simple domain model will contain an object that represents an order and an object that represents a line item for an order. The order object will have a one-to-many relationship to a collection of line item objects. The example code has two simple objects in the domain layer:

    com.meagle.bo.Order.java: contains the header-level information for an order.

    com.meagle.bo.OrderLineItem.java: contains the detail-level information for an order.

    Consider choosing package names for your objects that reflect how your application is layered. For example, the domain objects in the sample application can be located in the com.meagle.bo package. More specialized domain objects would be located in subpackages under the com.meagle.bo package. The business logic begins in the com.meagle.service package and DAO objects are located in the com.meagle.service.dao.hibernate package. The presentation classes for forms and actions reside in com.meagle.action and com.meagle.forms, respectively. Accurate package naming provides a clear separation for the functionality that your classes provide, allows for easier maintenance when troubleshooting, and provides consistency when adding new classes or packages to the application.

    领域对象层

    因为这些对象将和所有层交互,这也许是一个开始编码的好地方。这个简单的领域模型将包括一个代表一份订单的对象和一个代表一个订单项的对象。订单对象将和一组订单项对象有一对多的关系。例子代码在领域层有两个简单的对象:

    com.meagle.bo.Order.java: 包括一份订单的概括信息;

    com.meagle.bo.OrderLineItem.java: 包括一份订单的详细信息;

    考虑为你的对象选择包名,它将反映你的应用是怎样分层的。例如:简单应用的领域对象可以放进com.meagle.bo包[译者注:bo-business object?]。更多专门的领域对象将放入在com.meagle.bo下面的子包里。业务逻辑在com.meagle.service包里开始,DAO对象被放进com.meagle.service.dao.hibernate包。对于forms和actions的表现类分别驻入com.meagle.action 和 com.meagle.forms包。准确的包命名为你的类提供的功能提供一个清楚的区分,考虑到当故障维护时更易于维护,当增加新的类或包给应用时提供一致性。

    Persistence Layer Configuration

    There are several steps involved in setting up the persistence layer with Hibernate. The first step is to configure our domain business objects to be persisted. Since Hibernate works with POJOs we will use our domain objects for persistence. Therefore the Order and OrderLineItem objects will need to provide getter and setter methods for all fields that they contain. The Order object would contain setter and getter methods such as ID, UserName, Total, and OrderLineItems in a standard JavaBean format. The OrderLineItem would similarly follow the JavaBean format for its fields.

    Hibernate maps domain objects-to-relational databases in XML files. For our Order and OrderLineItem objects there will be two mapping files to express this. There are tools such as XDoclet to assist with this mapping. Hibernate will map the domain objects to these files:

    Order.hbm.xml

    OrderLineItem.hbm.xml

    You will find these generated files in the WebContent/WEB-INF/classes/com/meagle/bo directory. The Hibernate SessionFactory is configured to know which database it is communicating with, the DataSource or connection pool to use, and what persistent objects are available for persistence. Session objects provided by the SessionFactory are the interface used to translate between Java objects and persistence functions such as selecting, saving, updating, and deleting objects. We will discuss configuring the SessionFactory that Hibernate requires to handle Session objects in a later section.

    持久层配置

    用Hibernate设置持久层涉及到几个步骤。第一步是配置我们的被持久化的领域对象。因为Hibernate和POJOs[译者注:Persistence Objects Java Objects?]一起工作,我们将使用我们的领域对象持久化。因此,订单和订单项对象将需要提供它们包括的所有的字段的getter和setter方法。订单对象将包括像ID、用户名、合计、和订单项这样一些字段的以一种标准的JavaBean的格式的setter和getter方法。订单项对象将同样的用JavaBean的格式为它的字段设置setter和getter方法。

      Hibernate在XML文件里映射领域对象到关系数据库。为我们的订单和订单项对象将有两个映射文件来表达这种映射。有像XDoclet这样的工具来帮助这种映射。Hibernate将映射领域对象到这些文件:

    Order.hbm.xml

    OrderLineItem.hbm.xml

    你可以在WebContent/WEB-INF/classes/com/meagle/bo目录里找到这些生成的文件。Hibernate SessionFactory被配置来知道它正和哪种数据库交流、使用哪种数据源或连接池、什么持久的对象被持久化是有效的。被SessionFactory提供的Session对象是用于在Java对象和像选取、保存、更新、删除对象这样的一些持久化功能间的翻译的接口。我们将在后面的小节讨论配置Hibernate处理Session对象需要的SessionFactory。

    Business Layer Configuration

    Now that we have our domain objects we need to have business service objects that perform application logic, make calls to the persistence layer, take requests from the UI layer, deal with transactions, and handle exceptions. To wire all of this together and make this easy to manage we will use the bean management aspect of the Spring framework. Spring uses inversion of control (IoC), or setter dependency injection, to wire up objects that are referenced in an external XML file. Inversion of control is a simple concept that allows objects to accept other objects that are created at a higher level. This way your object is free from having to create objects and reduces object coupling.

    Here is an example of an object creating its dependencies without IoC, which leads to tight object coupling:

    Figure 2. Objects arranged without IoC. Object A creates objects B and C.

    And here is an example with IoC that allows objects to be created at higher levels and passed into objects so that they can use the implementations directly:

    Figure 3. Objects arranged with IoC. Object A contains setter methods that accept interfaces to objects B and C. This could have also been achieved with constructors in object A that accepts objects B and C.

    业务层配置

      现在,我们有了我们的领域对象,我们需要有业务服务对象来执行应用逻辑、执行向持久层的调用、获得从用户界面层的请求、处理事务、处理异常。为了把所有这些连在一起使它易于管理,我们将使用Spring框架的bean管理方面的功能。Spring使用“控制反转”(IoC),或者“setter依赖注入”来把这些对象连好,这些对象在一个外部的XML文件中被引用。“控制反转”是一个简单的概念,它允许对象接受其它在一个高一些的层次创建的对象。使用这种方法,你的对象从必须创建其它对象中解放出来和减少对象耦合。

      这儿是个不使用IoC的对象创建它的从属对象的例子,这导致紧的对象耦合:

      图2:没有使用IoC的对象组织。对象A创建对象B和C。

      这儿是一个使用IoC的例子,它允许对象在一个高一些层次被创建和传进对象,所以它们能直接使用现存的对象:

      图3:对象使用IoC组织。对象A包含setter方法,它们接受到对象B和C的接口。这也可以用对象A里的接受对象B和C的构建器完成。

    Building Our Business Service Objects

    The setters we will use in our business objects accept interfaces that allow loosely defined implementations of the objects that will be set, or injected. In our case we will allow our business service object to accept a DAO to handle the persistence of our domain objects. While the examples in this article use Hibernate, we can easily switch implementations to a different persistence framework and inform Spring of the new implementation DAO object to use. You can see how programming to interfaces and using the dependency injection pattern loosely couples your business logic from your persistence mechanism.

    Here is the interface for the business service object that is stubbed for a DAO object dependency:

    建造我们的业务服务对象

      我们将在我们的业务对象中使用的setter方法接受接口,这些接口允许将被设置或者注入的对象的宽松实现。在我们这个例子里我们将允许我们的业务服务对象接受一个DAO去控制我们的领域对象的持久化。虽然在这篇文章的例子中使用Hibernate,我们可以容易的转换到一个不同的持久框架的实现,通知Spring使用新的实现的DAO对象。你将看见怎样编程到接口和使用“依赖注入”模式宽松耦合你的业务逻辑和你的持久化机制。

      这儿是业务服务对象的接口,它有一个DAO对象依赖的桩。[译者注:是setOrderDAO方法吗?]

    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);

    }

    Notice that the code above has a setter for a DAO object. There is not a getOrderDAO method because it is not necessary since there is often no need to access the wired OrderDAO object from the outside. The DAO object will be used to communicate with our persistence layer. We will wire the business service object and the DAO object together with Spring. Because we are coding to interfaces, we do not tightly couple the implementation.

      注意上面的代码有一个为DAO对象准备的setter方法。这儿不是一个getOrderDAO方法因为它不是必要的,因为不太有从外面访问连着的OrderDAO对象的需要。DAO对象将被用来和我们的持久层沟通。我们将用Spring把业务服务对象和DAO对象连在一起。因为我们编码到接口,我们不会紧耦合实现。

    The next step is to code our DAO implementation object. Since Spring has built-in support for Hibernate this example DAO will extend the HibernateDaoSupport class, which allows us to easily get a reference to a HibernateTemplate, which is a helper class that simplifies coding with a Hibernate Session and handles HibernateExceptions. Here is the interface for the DAO:

    下一步是写我们的DAO实现对象。因为Spring有Hibernate内建的支持,这个例子DAO将继承HibernateDaoSupport类,它[译者注:英语语法问题:它是指“例子DAO”还是指“HibernateDaoSupport类”?]允许我们容易取得一个到HibernateTemplate的引用,HibernateTemplate是一个帮助类,它能简化Hibernate Session的编码和处理HibernateExceptions。这儿是DAO的接口:

    public interface IOrderDAO {

      public abstract Order findOrderById(

                                        final int id);

      public abstract List findOrdersPlaceByUser(

                               final String placedBy);

      public abstract Order saveOrder(

                                   final Order order);

    }

    We still have a couple more objects to wire together for our business layer. This includes the HibernateSessionFactory and a TransactionManager object. This is done directly in the Spring configuration file. Spring provides a HibernateTransactionManager, which will bind a Hibernate Session from the factory to a thread to support transactions (see ThreadLocal for more information). Here is the Spring configuration of the HibernateSessionFactory and the HibernateTransactionManager:

      我们还有两个对象要和我们的业务层连在一起。这包括HibernateSessionFactory和一个TransactionManager对象。这在Spring配置文件里直接完成。Spring提供一个HibernateTransactionManager,它将从工厂绑定一个Hibernate Session到一个线程来支持事务(见ThreadLocal获取更多的信息)。这儿是HibernateSessionFactory和HibernateTransactionManager的Spring配置。

    <bean id="mySessionFactory"

           class="org.springframework.orm.hibernate.

                  LocalSessionFactoryBean">

      <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">

            net.sf.hibernate.dialect.MySQLDialect

          </prop>

          <prop key="hibernate.show_sql">

            false

          </prop>

          <prop key="hibernate.proxool.xml">

            C:/MyWebApps/.../WEB-INF/proxool.xml

          </prop>

          <prop key="hibernate.proxool.pool_alias">

              spring

          </prop>

        </props>

      </property>

    </bean>

    <!-- Transaction manager for a single Hibernate

    SessionFactory (alternative to JTA) -->

    <bean id="myTransactionManager"

             class="org.

                    springframework.

                    orm.

                    hibernate.

                    HibernateTransactionManager">

      <property name="sessionFactory">

        <ref local="mySessionFactory"/>

      </property>

      </bean>

    Each object can be referenced in the Spring configuration within a <bean> tag. In this case the bean mySessionFactory represents a HibernateSessionFactory and the bean myTransactionManager represents a Hibernate transaction manager. Notice that the transactionManger bean has a property element called sessionFactory. The HibernateTransactionManager class has a setter and getter for sessionFactory, which is used for dependency injection when the Spring container starts. The sessionFactory property references the mySessionFactory bean. These two objects will now be wired together when the Spring container initializes. This wiring relieves you from creating singleton objects and factories for referencing and creating these objects, which reduces code maintenance in your application. The mySessionFactory bean has two property elements, which translate to setters for mappingResources and hibernatePropertes. Normally, this configuration would be stored in the hibernate.cfg.xml file if you were using Hibernate outside of Spring. However, Spring provides an easy way to incorporate the Hibernate configuration within the Spring configuration file. For more information see the Spring API.

     

      每一个对象能被Spring配置里的一个<bean>标记引用。在这个例子里,bean “mySessionFactory”代表一个HibernateSessionFactory,bean “myTransactionManager”代表一个Hibernate transaction manager。注意transactionManger bean有一个叫作sessionFactory的属性元素。HibernateTransactionManager有一个为sessionFactory准备的setter和getter方法,它们是用来当Spring容器启动时的依赖注入。sessionFactory属性指的是mySessionFactory bean。这两个对象现在当Spring容器初始化时将被连在一起。这种连接把你从为引用和创建这些对象而创建singleton对象和工厂中解放出来,这减少了你的应用中的代码维护。mySessionFactory bean有两个属性元素,它们转换到为mappingResources 和 hibernatePropertes的setter方法。通常,如果你在Spring外面使用Hibernate,这个配置将被保存在hibernate.cfg.xml文件中。然而,Spring提供一个容易的方法在Spring配置文件内合并Hibernate配置。获得更多的信息看Spring API.

    [注:由admin翻译上述部分2005年12月31日17:45分;由***在***修改了上述部分;由***在***修改了上述部分...请自行填写,以便联系] 

    相关资源

    转自:http://www.onjava.com/pub/a/onjava/2004/04/07/wiringwebapps.html?page=2 

Comments are closed.