<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    AppFuse學習筆記-模型層

    3.3 模型層結構
        Model層為整個系統的核心部分,完成應用的業務邏輯及與數據庫的通信。AppFuse中將Model分為兩層:持久層和業務層。采用Spring+Hibernate框架實現,這里以對用戶User數據的操作為例詳細闡述其實現方式。

        對持久化數據的訪問基于DAO(Data Access Object)模式實現。DAO模式提供了訪問關系型數據庫系統所需的所有接口操作的接口。DAO模式將底層數據訪問操作與高層業務邏輯分離開,對上層提供面向對象的數據訪問接口。

        Model層與User相關的類有:
        POJO:
        User:管理員表的業務對象。
        業務層:
        UserManager:業務層接口,為控制層所調用。
        UserManagerImpl:業務層接口的實現,調用持久層接口。
        持久層:
        UserDAO:持久層接口,為業務層實現所調用。
        UserDAOHibernate:持久層接口的實現。
        XML配置文件:
        applicationContext-service.xml:業務層接口的配置文件。
        applicationContext-hibernate.xml:持久層接口的配置文件。

    3.3.2 Spring的IoC
        Ioc(Inversion of Control)即反轉控制。Ioc模式即Dependency Injection模式是依賴注射的意思,也就是將依賴先剝離,然后在適當時候再注射進入。
        Spring的輕量級的bean容器為業務對象(business objects)、DAO對象和資源(如:JDBC數據源或者Hibernate SessionFactorie等)對象提供了IoC類型的裝配能力。Spring使用一個xml格式的應用配置文件為開發者提供了一種通過解析定制的屬 性文件來手動管理單實例對象或者工廠對象的選擇性。由于Spring將非入侵性做為一個重要的目標,因此可以由Spring配置管理的bean對象均不需 要依賴Spring自有的接口和類就可以通過它們的bean屬性完成配置。
        就實現上來講Spring采取了配置文件的形式來實現依賴的注射,并且支持Type2 IOC(Setter Injection)以及Type3 IOC(Constructor Injection)。
        在Model層,使用Spring提供的Setter Injection(type2)注入方式。以User為例,下面是其用法。
        在applicationContext- hibernate.xml中定義
        <bean id="userDAO" class="org.appfuse.dao.hibernate.UserDAOHibernate">
            <property name="sessionFactory"><ref local="sessionFactory"/></property>
        </bean>
        在UserManager類中有一句:
        public void setUserDAO(UserDAO dao);
        這就是一個DAO Object設置方法(注射器)。UserDAO將被調用,和持久層通信。以這種方式創建UserDAO的實例,同樣達到了由UserManager創建UserDao的目的。避免了直接實例化UserDAO的實現而使業務層和持久層緊密耦合。
     

        在控制層調用業務層方法時,使用服務定位器返回給Spring context,Spring的BeanFactory提供了getBean方法。BeanFactory是一個通用的Factory,它使對象能夠按名稱獲取,并且能管理對象之間的關系。
        在applicationContext-service.xml中配置
        <bean id="userManager" parent="txProxyTemplate">
            <property name="target">
                <bean class="org.appfuse.service.impl.UserManagerImpl">
                    <property name="userDAO"><ref bean="userDAO"/></property>
                </bean>
            </property>
        </bean>
        在控制層BaseAction定義通用方法:
        private static ApplicationContext ctx = null;
        public Object getBean(String name) {
            if (ctx == null) {
                ctx = WebApplicationContextUtils
                        .getRequiredWebApplicationContext(servlet.getServletContext());
            }
            return ctx.getBean(name);
        }
        在UserAction中創建UserManager的實例:
            UserManager mgr = (UserManager) getBean("userManager");
        這樣,通過BeanFactory的getBean方法,以及xml配置文件,避免了在UserAction類中直接實例化UserManager,消除了控制層與業務層及業務層與持久層之間的耦合,實現了依賴的注射。
        ApplicationContext 是BeanFactory的子接口,為下列東西提供支持:
            信息查找,支持著國際化
            事件機制,允許發布應用對象以及可選的注冊以接收到事件
            可移植的文件和資源訪問

    3.3.3 Spring的事務管理
        在數據持久層的杰出貢獻,可能是Spring最為閃亮的優點。
        Spring提供了通過容器的集約式參數化事務機制,實現事務的外部管理。容器管理的參數化事務為程序開發提供了相當的靈活性,同時因為將事務委托給容器 進行管理,應用邏輯中無需再編寫事務代碼,大大節省了代碼量(特別是針對需要同時操作多個事務資源的應用),從而提高了生產率。
        AppFuse在applicationContext-service.xml文件中進行了對事務的配置
        <bean id="txProxyTemplate" abstract="true"
            class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
            <property name="transactionManager"><ref bean="transactionManager"/></property>
            <property name="transactionAttributes">
                <props>
                    <prop key="save*">PROPAGATION_REQUIRED</prop>
                    <prop key="remove*">PROPAGATION_REQUIRED</prop>
                    <prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
                </props>
            </property>
        </bean>
        這里定義了一個名為txProxyTemplate的TransactionProxyFactoryBean服務。它對包含實際數據邏輯的持久層對象進 行了事務的封裝。在這里,通過transactionAttributes屬性,我們指定了事務的管理策略,即將所有的名稱以save和remove開頭 的方法納入事務管理范圍。如果此方法中拋出異常,則Spring將當前事務回滾,如果方法正常結束,則提交事務。
        而對所有其它方法則以只讀的事務處理機制進行處理。設為只讀型事務,可以使持久層嘗試對數據操作進行優化,如對于只讀事務Hibernate將不執行flush操作,而某些數據庫連接池和JDBC 驅動也對只讀型操作進行了特別優化。
        如果有其他的方法需要進行寫數據庫操作,可以在相應的Manager配置中聲明。如在UserManager中,就添加了屬性
            <property name="transactionAttributes">
                <props>
                    <prop key="save*">PROPAGATION_REQUIRED</prop>
                    <prop key="remove*">PROPAGATION_REQUIRED</prop>
                    <prop key="*LoginCookie">PROPAGATION_REQUIRED</prop>
                    <prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
                </props>
            </property>
        這樣,以LoginCookie結尾的方法也可以寫數據庫了。
        Spring可以將任意Java Class 納入事務管理,而無需對其進行任何修改,因此我們的類可能完全不知道它正在被進行事務管理。


    3.3.3 Spring+Hibernate操作持久層
        Spring對Hibernate有很好的支持。
        Hibernate中通過SessionFactory創建和維護Session。Spring對SessionFactory的配置進行了整合,無需再 通過Hibernate.cfg.xml對SessionFactory進行設定。SessionFactory節點的mappingResources 屬性包含了映射文件的路徑,list節點下可配置多個映射文件。hibernateProperties節點則容納了所有的屬性配置。可以對應傳統的 Hibernate.cfg.xml文件結構對這里的SessionFactory配置進行解讀。
        下面是HibernateSessionFactory 和 HibernateTransactionManager的配置:
        在applicationContext-hibernate.xml中:
        <bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
            <property name="dataSource"><ref bean="dataSource"/></property>
            <property name="mappingResources">
                <list>
                    <value>com/mycompany/model/User.hbm.xml</value>
                    ……………………………
                </list>
            </property>

            <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">@HIBERNATE-DIALECT@</prop>
                <!--prop key="hibernate.show_sql">true</prop-->
                <!--prop key="hibernate.hbm2ddl.auto">update</prop-->
            </props>
            </property>
        </bean>

        Spring 提供了一個 HibernateTransactionManager,采用面向Hibernate的TransactionManager實現: org.springframework.orm.hibernate.HibernateTransactionManager。他用線程捆綁了一個 Hibernate Session,用它來支持transactions。
        <bean id="transactionManager" class="org.springframework.orm.hibernate.HibernateTransactionManager">
            <property name="sessionFactory"><ref local="sessionFactory"/></property>
        </bean>

        sessionFactory Bean引用了HibernateSessionFactory,而transactionManager Bean引用了HibernateTransactionManage。 transactionManager Bean中有個sessionFactory屬性。 HibernateTransactionManager有個sessionFactory setter 和 getter方法,用來在Spring啟動的時候實現“依賴注入” (dependency injection)的。 在sessionFactory 屬性里引用sessionFactory Bean。這兩個對象在Spring容器初始化后就被組裝了起來了。
     
        User使用一個TransactionProxyFactoryBean,它定義了一個setTransactionManager()。能很方便的處 理申明的事物還有Service Object。TransactionProxyFactoryBean 還有個setter. 這會被Business service object(UserManager)引用, UserManager定義了業務層,并且它還有個屬性,由setUserDAO()引用。

        系統持久層中所有的類都繼承自Spring提供的HibernateDaoSupport類,HibernateSupport實現了 HibernateTemplate和SessionFactory實例的關聯。HibernateTemplate對Hibernate Session操作進行了封裝,提供了一個簡單的方式實現了Hibernate-based DAO對象。借助HibernateTemplate我們可以脫離每次數據操作必須首先獲得Session實例、啟動事務、提交/回滾事務以及煩雜的 try/catch/finally的繁瑣操作。一個簡單的Hibernate訪問方法就完全解決了些麻煩! 無論是在多個DAO接口還是在多方事務的情況下,Spring使得多種DAO對象無縫地協同工作。
        對于簡單的單步的動作,象find, load, saveOrUpdate或者delete的調用,HibernateTemplate提供更為便利的選擇以代替象一行的回調的執行。此外 HibernateDaoSupport類提供了setSessionFactory方法來接受一個SessionFactory,同時提供了 getSessionFactory和getHibernateTemplate方法供其繼承類使用。將這些結合起來,允許對于典型的需求給出了非常簡單 的DAO實現,如獲得所有用戶的方法:
        public List getUsers(User user) {
            return getHibernateTemplate().find("from User u order by upper(u.username)");
        }


    posted on 2007-06-18 18:09 chenguo 閱讀(151) 評論(0)  編輯  收藏 所屬分類: J2ee Dev

    <2025年5月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    導航

    統計

    留言簿

    隨筆分類(1)

    文章分類(52)

    好友 小山的博客

    最新隨筆

    最新評論

    主站蜘蛛池模板: 你懂的在线免费观看| 青娱乐免费视频在线观看| 亚洲一级二级三级不卡| 成年人视频免费在线观看| 亚洲av成人无码网站…| 亚洲Av综合色区无码专区桃色| 91成人免费观看网站| 老司机午夜在线视频免费| 91亚洲va在线天线va天堂va国产| 好爽又高潮了毛片免费下载| 3344在线看片免费| 亚洲高清国产拍精品熟女| 亚洲AV永久无码精品水牛影视| 在线播放免费播放av片| 日本一道本不卡免费| 亚洲爆乳无码精品AAA片蜜桃| 久久久久亚洲av无码尤物| 免费一级毛片在级播放| 18pao国产成视频永久免费| 色婷婷综合缴情综免费观看| 亚洲Av无码一区二区二三区| 久久夜色精品国产亚洲av | 成年人免费的视频| 国产精品永久免费| 亚洲AV无码成人网站在线观看| 亚洲午夜精品久久久久久人妖| 亚洲国产综合无码一区二区二三区 | 亚洲春黄在线观看| 亚洲欧洲无码AV电影在线观看| 免费网站看v片在线香蕉| 91免费国产精品| 51午夜精品免费视频| 国产亚洲一卡2卡3卡4卡新区| 亚洲综合小说久久另类区| 亚洲区小说区激情区图片区| 亚洲av无码乱码在线观看野外 | 永久在线免费观看| 成全视频在线观看免费| 一级做α爱过程免费视频| 色屁屁www影院免费观看视频| 亚洲日韩中文字幕一区|