《經久不衰的Spring框架:Spring+SpringMVC+MyBatis 整合》


前言

  主角即Spring、SpringMVC、MyBatis,即所謂的SSM框架,大家應該也都有所了解,概念性的東西就不寫了,有萬能的百度。之前沒有記錄SSM整合的過程,這次剛剛好基於自己的一個小項目重新搭建了一次,而且比項目搭建的要更好一些。以前解決問題的過程和方法並沒有及時記錄,以后在自己的小項目中遇到我再整理分享一下。個人認為使用框架並不是很難,關鍵要理解其思想,這對於我們提高編程水平很有幫助。 

  工作環境:JDK 1.7、Mysql 5.6、Myeclipse 10、Tomcat 7、Maven

  框架版本:Spring 4.2.6.RELEASE、SpringMVC 4.2.6.RELEASE、MyBatis 3.2.8

  

一、整體文件結構設計

項目目錄結構:

      

 

  1、類文件和資源文件分開存放,類文件分為六層,其中common存放公共和框架部分,controller存放項目控制層,service存放項目業務邏輯層,model存放項目實體類,mapper存放數據層接口,test存放測試相關類。

  注:若涉及到多業務模塊的情況,分層可以在各層內部進行划分,當然對於大模塊建議采用Maven多模塊項目方式搭建。

  2、前端在webapp下分出了common和project,common存放公共部分,project內部用於存放多個子模塊,common以及各子模塊內部分別新建images,js,css和view四個文件夾,用於歸類不同資源。

 

二、項目入口web.xml

  構建好整體結構后,接下來應該把目光看下web.xml文件,無論是何種JavaEE框架,入口總是在web.xml,認准這邊就沒錯了。

  web.xml 內容很多,SSM整合相關的關鍵部分就是加載Spring配置文件spring-config.xml,以及將SpringMVC核心調度器DispatcherServlet注冊為servlet(配置文件為mvc-config.xml),其他部分有注釋,選擇性觀看即可。

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
  
    <!-- ================站台名稱,站台描述,大小圖標================ --> 
    <display-name>SpringMVC</display-name>
    <description>柴可夫斯基模板</description>
      <icon>
         <small-icon>/common/images/favicon.ico</small-icon>
       <large-icon>/common/images/favicon.ico</large-icon>
    </icon>
  
    <!-- 支持分布式 -->
    <!-- <distributable/> -->

    <!-- 應用路徑,如果不設置,缺省為"webapp.root",當tomcat加載多個項目時,會發生名稱沖突 -->  
    <context-param>  
        <param-name>webAppRootKey</param-name>  
        <param-value>spring4.root</param-value>  
    </context-param> 
    
    <!-- ================log4j配置開始================ --> 
    <!-- log4j2不需要在這邊做額外的配置 -->
    <!-- ================log4j配置結束================ --> 
    
    <!-- ================Spring配置開始================ --> 
    <!-- 設置Spring容器加載所有的配置文件的路徑 -->
    <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath*:spring-config.xml</param-value>
      <!-- <param-value>classpath:/spring-*.xml</param-value> -->
    </context-param>
    <!-- 配置Spring監聽器,可以在容器啟動時,加載contextConfigLocation的context-param節點的配置文件 -->
    <listener>
      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <!-- ================Spring配置結束================ -->
    
    
    <!-- 配置監聽器,定義在服務器啟動和關閉時,需要執行的方法 -->
    <listener>
      <listener-class>com.demo.common.startup.InitListener</listener-class>
    </listener>
    
    <!-- 防止Struts和Quartz等內存溢出監聽器 -->
    <listener>
      <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
    </listener>
    
    <!-- 監聽HTTP請求事件,為Bean的request,session,globalsession等作用域提供支持 -->
    <listener>
        <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
    </listener>
    
    <!-- Spring 字符編碼配置 --> 
    <filter>
      <filter-name>characterEncodingFilter</filter-name>
      <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
      <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
      </init-param>
      <init-param>
        <param-name>forceEncoding</param-name>
        <param-value>true</param-value>
      </init-param>
    </filter>
    <filter-mapping>
      <filter-name>characterEncodingFilter</filter-name>
      <url-pattern>/*</url-pattern>
    </filter-mapping>
  
    <!-- 自定義登錄過濾器,攔截JSP頁面,不允許直接訪問 -->
    <filter>
      <filter-name>loginFilter</filter-name>
      <filter-class>com.demo.common.filter.LoginFilterSpring</filter-class>
      <init-param>
        <param-name>charset</param-name>
        <param-value>UTF-8</param-value>
      </init-param>
      <init-param>
        <param-name>contentType</param-name>
        <param-value>text/html;charset=UTF-8</param-value>
      </init-param>
    </filter>
    <filter-mapping>
      <filter-name>loginFilter</filter-name>
      <url-pattern>*.jsp</url-pattern>
    </filter-mapping>
    
    <!--包裝request過濾器-->
    <filter>
        <filter-name>wrapRequestFilter</filter-name>
        <filter-class>com.demo.common.filter.WrapParameterFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>wrapRequestFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
    <!-- 激活Tomcat的defaultServlet來處理靜態文件(效率較高) -->  
    <servlet-mapping>
      <servlet-name>default</servlet-name>
      <url-pattern>*.jpg</url-pattern>
      <url-pattern>*.gif</url-pattern>
      <url-pattern>*.png</url-pattern>
      <url-pattern>*.js</url-pattern>
      <url-pattern>*.css</url-pattern>
      <url-pattern>*.ico</url-pattern>
      <url-pattern>*.eot</url-pattern>
      <url-pattern>*.svg</url-pattern>
      <url-pattern>*.ttf</url-pattern>
      <url-pattern>*.woff</url-pattern>
      <url-pattern>*.mp3</url-pattern>
      <url-pattern>*.html</url-pattern>
    </servlet-mapping>
    
    <!-- ================配置SpringMVC核心調度器================ -->
    <!-- 不指定具體文件的話,默認為"/WEB-INF/<servlet name>-servlet.xml" -->
    <!-- load-on-startup代表啟動順序,設置為大於等於0表示容器在應用啟動時就加載並初始化這個servlet -->
    <!-- 推薦攔截/,風格優雅 -->
    <servlet>
      <servlet-name>SpringMVC</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:mvc-config.xml</param-value>
      </init-param>
      <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
      <servlet-name>SpringMVC</servlet-name>
      <url-pattern>/</url-pattern>
    </servlet-mapping>
    
    <!-- 隨服務器啟動的servlet --> 
    <servlet>
      <servlet-name>initServlet</servlet-name>
      <servlet-class>com.demo.common.startup.InitServlet</servlet-class>
      <load-on-startup>0</load-on-startup>
    </servlet>
    
    <!-- 阿里巴巴數據源配置啟用Web監控統計功能 -->
    <!-- 通過 http://ip:port/druid/ 地址訪問即可 -->
    <servlet>
      <servlet-name>DruidStatView</servlet-name>
      <servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>
      <init-param>
            <param-name>allow</param-name>
            <param-value>127.0.0.1</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
      <servlet-name>DruidStatView</servlet-name>
      <url-pattern>/druid/*</url-pattern>
    </servlet-mapping>
    
    <!-- CXF服務發布配置 -->
    <servlet>
        <servlet-name>CXFService</servlet-name>
        <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
        <load-on-startup>1</load-on-startup> 
    </servlet>
    <servlet-mapping>
        <servlet-name>CXFService</servlet-name>
        <url-pattern>/webservice/*</url-pattern>
    </servlet-mapping>
    
    <!-- 設置session過期時間為60分鍾 -->
    <session-config>
      <session-timeout>60</session-timeout>
    </session-config>
    
    <!-- 指定錯誤404和500的處理頁面 -->
    <error-page>
      <error-code>404</error-code>
      <location>/common/view/404.jsp</location>
    </error-page>
    <error-page>
      <error-code>500</error-code>
      <location>/common/view/500.jsp</location>
    </error-page>
    
    <!-- 歡迎頁面 -->
    <welcome-file-list>
      <welcome-file>common/view/index.jsp</welcome-file>
    </welcome-file-list>

</web-app>

 

三、Spring 框架配置

這塊涉及內容也很多,從何說起呢,先上一下文件內容好了:

spring-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:task="http://www.springframework.org/schema/task"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-3.1.xsd
    http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">
    
    <!-- 加載配置屬性文件 -->
    <context:property-placeholder ignore-unresolvable="true" location="classpath:constant.properties"/>
    
    <!-- 開啟異步任務(同時開啟定時器注解掃描) -->
    <task:annotation-driven />
    
    <!-- 使用@AspectJ風格的切面聲明 -->
    <!-- <aop:aspectj-autoproxy/> -->
    
    <!-- 使用Annotation自動注冊Bean -->
    <!-- 在主容器中不掃描@Controller注解,在SpringMvc中只掃描@Controller注解 -->
    <context:component-scan base-package="com.demo"><!-- base-package 如果多個,用“,”分隔 --> 
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
    </context:component-scan>  
    
    <!-- 引入Mybatis配置 -->
    <import resource="spring-mybatis.xml"/>
    
    <!-- 引入Socket配置 -->
    <import resource="spring-socket.xml"/>
    
    <!-- 引入MongoDB配置 -->
    <import resource="test/mongo-config.xml"/>
    
    <!-- 引入定時器任務配置 -->
    <!-- <import resource="classpath*:com/demo/config/spring-job.xml"/> -->
    
    <!-- 引入hibernate4配置 -->
    <!-- <import resource="spring-hibernate.xml"/> -->
    
    <!-- 引入緩存配置 -->
    <!-- <import resource="spring-cache.xml"/> -->
    
    <!-- 引入CXF配置 -->
    <import resource="test/spring-cxf.xml"/>
    
    <!-- 引入Redis配置(無需如此配置,直接使用RedisUtil即可) -->
    <!-- <import resource="test/spring-jedis.xml"/> -->
</beans>

上面內容很多,但是並不全是SSM框架的,需要關注的點只有下面幾個:

1、context:component-scan 包掃描

  這個注解不用多說了,要注意的就是主容器中不掃描@Controller注解,因為@Controller將會在SpringMVC掃描。

2、import 標簽和多文件配置

  在團隊開發時候,每個人都常去改動Spring配置文件,不科學,使用這個技巧方便,每個都有各自的配置文件了。項目較大,有較多的bean時,可以將其分散到子文件中。雖然Spring還有自動掃描的功能,但我感覺也不怎么好,需要去掃描,影響性能;而且各個Bean分散在不同包中,不好配置。

  多文件配置通常有兩種做法:

  2.1 在 web.xml配置中的contextConfigLocation節點配置多個值。

具體代碼如下:

<context-param> 
   <param-name>contextConfigLocation</param-name> 
   <param-value> 
      /WEB-INF/classes/context1.xml, 
       /WEB-INF/classes/context2.xml, 
       /WEB-INF/classes/context3.xml    
    </param-value> 
</context-param> 

  其中分隔符可以是","也可以是" "等,也可以用通配符application-*,這樣配置的要求是,你的Spring配置文件必須是applicationContext-*****.xml這樣的形式存在,*號代表通配符,具體就不說了。 

     2.2 在一個application.xml中配置多個import標簽引入其他文件。

  個人喜歡這種方式,清晰明了,總得有一個主入口吧(估計受了webpack和SeaJS的影響)。

  從這邊也不難看到Spring框架在其中扮演的角色:管理容器,有效地組織你的中間層對象(無節操得集成其他框架)。

3、引入mybatis配置:spring-mybatis.xml

  這個文件就是用來完成spring和mybatis的整合的。這里面也沒多少行配置,主要的就是自動掃描,自動注入,配置數據庫。注釋也很詳細,大家看看就明白了。

spring-mybatis.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-3.1.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
    
    <!-- 1. 數據源配置 -->
    <context:property-placeholder ignore-unresolvable="true" location="classpath:jdbc.properties" />
    
    <!-- Druid方式配置數據源 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">  
    
        <!-- 基本屬性 url、user、password -->
        <property name="driverClassName" value="${jdbc.driverClassName}" />
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
    
        <!-- 配置初始化大小、最小、最大 -->
        <property name="initialSize" value="10" />  
        <property name="minIdle" value="20" />  
        <property name="maxActive" value="100" />  
        
        <!-- 配置獲取連接等待超時的時間 -->
        <property name="maxWait" value="60000" />  
    
        <!-- 配置間隔多久才進行一次檢測,檢測需要關閉的空閑連接,單位是毫秒 -->
        <property name="timeBetweenEvictionRunsMillis" value="6000" />  
        
        <!-- 配置一個連接在池中最小生存的時間,單位是毫秒 -->
        <property name="minEvictableIdleTimeMillis" value="300000" />  
    
        <!-- 驗證是否回收 -->
        <property name="validationQuery" value="SELECT 'x' FROM DUAL" />  
        <property name="testWhileIdle" value="true" />  
        <property name="testOnBorrow" value="false" />  
        <property name="testOnReturn" value="false" /> 
    
        <!-- 開啟Druid的監控統計功能 -->  
        <property name="filters" value="stat" />  
    </bean> 
    
    <!-- 2. 創建SqlSession的工廠 -->
    <!-- dataSource:引用數據源,統一加載配置--> 
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">  

        <property name="dataSource" ref="dataSource" ></property>    

        <!-- 自動配置別名-作用類似mybatis-config.xml的別名 -->  
        <property name="typeAliasesPackage" value="com.demo.model" />
        
        <!-- 設置別名的類加上父類限定 -->  
        <property name="typeAliasesSuperType" value="com.demo.common.base.BaseEntity"/>
        
        <!-- 當mybatis的xml文件和mapper接口不在相同包下時,需要用mapperLocations屬性指定xml文件的路徑 -->   
        <!-- *是個通配符,代表所有的文件,**代表所有目錄下 --> 
        <property name="mapperLocations" value="classpath*:mappings/**/*.xml"/>
        
        <!-- 指定mybatis核心配置文件 --> 
        <property name="configLocation" value="classpath:mybatis-config.xml"></property>
    </bean>  

    <!-- 3. 自動掃描加載Sql映射文件/接口 -->
    <bean id="mapperScannerConfigurer"  class="org.mybatis.spring.mapper.MapperScannerConfigurer">

        <!-- sqlSessionFactoryBeanName:代表延遲加載-->
        <!-- 這個配置的前提條件是:映射接口類文件(.java)和映射XML文件(.xml)需要放在相同的包下(com.demo.mapper)-->
        <!-- <property name="sqlSessionFactory" ref="sqlSessionFactory"></property> -->
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />

        <!-- basePackage:指定sql映射文件/接口所在的包(自動掃描)-->
        <property name="basePackage" value="com.demo.mapper"></property>
    
        <!-- 掃描basePackage下所有以@MyBatisDao注解的接口 -->
        <property name="annotationClass" value="com.demo.common.persistence.annotation.MyBatisDao"/>
    </bean>
    
    <!-- 4. 事務管理 --> 
    <!-- dataSource:引用上面定義的數據源 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!-- 5. 使用聲明式事務 -->
    <!-- transaction-manager:引用上面定義的事務管理器 -->
    <!-- 配置 Annotation 驅動,掃描@Transactional注解的類定義事務  -->
    <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
    
    <!-- 定義JdbcTemplate的Bean -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" p:dataSource-ref="dataSource"></bean>
    
</beans>

 

四、SpringMVC 框架配置

  這塊配置里面的注釋也很詳細,在此就不說了,主要是自動掃描控制器,視圖模式,注解的啟動這三個。

mvc-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:mvc="http://www.springframework.org/schema/mvc" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-3.1.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">
    
    <!-- 打開使用注解自動檢測功能自動注冊Bean,只掃描@Controller -->
    <context:component-scan base-package="com.demo"  use-default-filters="false">      
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />    
    </context:component-scan>  
    
    <!-- 文件上傳表單的視圖解析器 -->  
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">  
        <property name="defaultEncoding" value="utf-8"></property>   
        <property name="maxUploadSize" value="2097152"></property><!--限制文件上傳2M內  -->   
        <property name="maxInMemorySize" value="40960"></property>  
    </bean>  
    
    <!-- 默認的注解映射的支持 - 增加String類型中文解析 -->  
    <mvc:annotation-driven>
        <mvc:message-converters>
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <constructor-arg value="UTF-8" />
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>
    
    <!-- 使用自定義Spring攔截器 -->
    <mvc:interceptors>    
      <mvc:interceptor>    
            <mvc:mapping path="/**" />     
            <bean class="com.demo.common.core.SpringMVCInterceptor"></bean>    
        </mvc:interceptor>    
    </mvc:interceptors>    
    
    <!-- 視圖配置 -->
    <!-- 對轉向頁面的路徑解析,指定輸出視圖的前后綴,controller返回的視圖直接加上此前后綴 --> 
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
        p:prefix="/project/" p:suffix=".jsp" />
        
</beans>

  這部分內容也可以參考上一篇博文:《經久不衰的Spring框架:SpringMVC 統括》

 

五、部署與測試

  到此,已經完成了SSM三大框架的整合了,接下來測試一下,如果成功了,那么恭喜你,如果失敗了,繼續調試吧,作為程序員就是不停的與BUG做斗爭!

    測試的話,無非就是新建對應的view、controller、service、mapper ,測試一下SpringMVC和Mybatis的功能,很簡單,就不羅嗦了。

  部署的話,就干到tomcat里面去,啟動,訪問localhost即可,也不贅述了。

  至此,SSM三大框架的整合就完成了,在此基礎上可再添加其他功能。

 

編后語

  由於這只是SSM整合的文章,所以上面很多文件內容沒有面面俱到,比如日志處理、socket、ws、bean定制等等,后續覺得有用得會繼續放上來,請繼續關注山人行博客。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM