1. 程式人生 > >Spring + SpringMVC + Druid + JPA(Hibernate impl) 給你一個穩妥的後端解決方案

Spring + SpringMVC + Druid + JPA(Hibernate impl) 給你一個穩妥的後端解決方案

解決方案

1. 采用到的開源項目漫談

Spring 迷人的依賴註入特性, 使其已經穩穩的占據在 JavaEE 項目引用開源項目列表中的上層位置。

秉承低耦合高內聚的遵旨, Spring 提倡的對象工廠解耦類關系的思想已深入到每個攻城獅的心中。

SpringMVC 做為 Spring 的幹兒子,最讓我沈醉的是她強大的擴展能力,深邃的像大海一樣。

前端無論是 freemarker/velocity/jsp...,後端 DAO 層無論是傳統的 ORM 還是新近上位的領域模型。

她的態度始終如一,給你360度最貼心的呵護,有一人對你如此,此生足矣。

官網地址:http://projects.spring.io/spring-framework/

項目中關於 SpringMVC + Spring 的依賴:

技術分享

       <!--spring mvc-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>4.3.3.RELEASE</version>
        </dependency>

        <!-- Spring-orm -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>4.3.3.RELEASE</version>
        </dependency>

        <!-- Spring AOP 動態代理 -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.9</version>
        </dependency>

技術分享

這上面我想說的是 AspectJ 這個東東, AspectJ 是最早、功能比較強大的 AOP 實現之一。

在 Java 領域,AspectJ 中的很多語法結構基本上已成為 AOP 領域的標準。

Spring 也有自己的 Spring-AOP,Spring-AOP 采用運行時生成代理類,底層可以選用 JDK 或者 CGLIB 動態代理。

通俗點,AspectJ 在編譯時增強要切入的類,而 Spring-AOP 是在運行時通過代理類增強切入的類,效率和性能可想而知。

所以 Spring 在 2.0 的時候就已經開始支持 AspectJ ,現在到 4.X 的時代已經很完美的和 AspectJ 結合到一起。

有興趣的可以在接著讀讀:https://www.oschina.net/translate/comparative_analysis_between_spring_aop_and_aspectj?cmp

Druid 出自阿裏巴巴技術團隊之手,個人認為是比較好的數據庫連接池之一,尤其是監控部分是我的最愛。

官方 github 地址:https://github.com/alibaba/druid/wiki/常見問題

項目中的 web.xml 配置監控配置和監控界面:

技術分享

   <!--Druid 數據庫連接池監控-->
    <servlet>
        <servlet-name>DruidStatView</servlet-name>
        <servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>DruidStatView</servlet-name>
        <url-pattern>/druid/*</url-pattern>
    </servlet-mapping>

技術分享

技術分享

JPA 作為 Sun 公司引入的 ORM 規範,就像是 JDBC 之於各種數據庫驅動 Jar,

不要去在意使用了什麽樣的數據庫,用 JDBC 提供的規範方法去擼代碼即可。

JPA 制定持久層規範,相同與抽象接口,有 ORM 框架擼具體的實現層。

Sun 想實現 ORM 技術統一,可能不遠的將來,你不用在糾結選擇什麽樣子的 ORM 框架。

而現有熱門的 ORM 框架會漸漸失去光澤,這畢竟是個漫長的過程,讓我們拭目以待。

回到頂部

2. 方案整體一覽

方案中所有的類都位於 SpringContext 中,由 Spring 統一進行管理。

讓 Spring 統一管理的前提是你要告訴有這樣一個類需要它管理,目前我接觸到的告訴途徑有兩種。

傳統的 xml 配置和註解方式,xml 配置和註解方式各有優劣,比如 xml 配置的優點:

a. 如果你公司項目在引用另外一個公司的 jar,這時候,唯一可行方式為 xml 配置。

b. 如果類之間的依賴關系變動頻繁,xml 配置是比較優秀的,改動代碼和改動配置文件,無論是技術上還是風險上,xml 都穩贏註解。

註解聲明的方式優點:代碼和聲明在一起,開發的時候不用切來切去,比 xml 配置聲明要簡單明了的多。

現在很多主流的框架都引入了註解,但也無法擯棄 xml 配置聲明的方式。

技術分享

在這個方案中我使用幹凈簡單註解的方式,controller [email protected],dao-impl [email protected],service [email protected]

技術分享

控制層註入服務實例,服務層註入數據訪問層對象,持久層對象由 JAP 進行註解,頁面通過控制層來傳輸和獲取數據。

web.xml:

技術分享 View Code

maven pom.xml:

技術分享 View Code

回到頂部

3. DAO 層的種種設計思路

Controller 和 Service 層非常容易理解,這裏不贅述了。

DAO 層 中 BasePo 希望將一些共有的屬性抽象在父類當中(屬性由具體項目需求決定)。

技術分享 BasePO

BaseDaoImpl 希望將一些公共的數據訪問方法實現在父類當中(我這裏的方法可能有點少,可以由具體項目增加)。

技術分享 BaseDaoImpl

使用 JAP 註解編寫業務使用到的持久層對象。

技術分享

@Entity
@Table(name = "t_user")public class User extends BasePO {
    @Column(nullable = false)
    String name;
    @Column(nullable = false)
    String pwd;
....getter/setter }

技術分享

配置啟動時掃描 POJO 的動作,至於是新建還是更新都有配置選項,可以自己查閱相關文檔。

技術分享

    <!-- 配置hibernate session工廠,需添加 spring-orm -->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
                <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
                <prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
            </props>
        </property>

        <!-- 自動掃描註解方式配置的hibernate類文件 -->
        <property name="packagesToScan">
            <list>
                <value>com.rambo.sdh.pojo</value>
            </list>
        </property>
    </bean>

技術分享

操縱數據庫最主要的事務管理,采用 AOP 聲明方式,在執行含有數據變動的方法前後進行攔截。

采用 AOP 聲明方式進行攔截的好處,不用去關註數據庫事務的開啟和關閉,將重心放到業務邏輯上面。

技術分享

<!-- 配置事務管理器 -->
    <bean name="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>

    <!-- 聲明式容器事務管理 ,transaction-manager指定事務管理器為transactionManager- -->
    <tx:advice id="transactionAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="add*"/>
            <tx:method name="save*"/>
            <tx:method name="update*"/>
            <tx:method name="modify*"/>
            <tx:method name="edit*"/>
            <tx:method name="delete*"/>
            <tx:method name="remove*"/>
            <tx:method name="repair"/>
            <tx:method name="deleteAndRepair"/>

            <tx:method name="get*" propagation="SUPPORTS"/>
            <tx:method name="find*" propagation="SUPPORTS"/>
            <tx:method name="load*" propagation="SUPPORTS"/>
            <tx:method name="search*" propagation="SUPPORTS"/>
            <tx:method name="datagrid*" propagation="SUPPORTS"/>
            <tx:method name="*" propagation="SUPPORTS"/>
        </tx:attributes>
    </tx:advice>
    <aop:config>
        <aop:pointcut id="transactionPointcut" expression="execution(* com.rambo.sdh.service..*Impl.*(..))"/>
        <aop:advisor pointcut-ref="transactionPointcut" advice-ref="transactionAdvice"/>
    </aop:config>

技術分享

上面配置文件的大體意思是說,在包 com.rambo.sdh.service..*Impl.* 下所執行的已 add/save/update.....開頭的方法。

方法在執行前後都會被 HibernateTransactionManager 攔截住,進行事務的開啟和關閉。

當然還有一些其他的事情,有興趣可以 debug 源碼去一探究竟。

貌似說的也差不多了,該方案為 javaweb 後端解決方案,前端用你想用的渲染技術即可。

項目開源 GIT 地址已在最上面給出,如果有興趣的可以檢出到本地跑一跑,該方案中小公司其實都挺適合,上手和開發速度快。


Spring + SpringMVC + Druid + JPA(Hibernate impl) 給你一個穩妥的後端解決方案