spring-mvc.xml 和 application-context.xml的配置與深入理解


 在java框架這個話題,前幾篇文章是基於搭建ssm項目框架,以及web.xml的配置講解,本篇主要就ssm框架的其他配置文件進行深入講解,他們分別是:1、application-context.xml;2、spring-mvc.xml。
 
回顧一下application-context.xml和spring-mvc.xml在web.xml中的配置是怎樣的。

(0)前沿

1、application-context.xml是全局的,應用於多個serverlet,配合listener一起使用,web.xml中配置如下: 

<!-- 配置監聽器 -->

復制代碼
<!-- 配置監聽器 -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>
 
復制代碼

2、spring-mvc.xml 是spring mvc的配置,web.xml中配置如下: 

<!--配置springmvc DispatcherServlet-->

復制代碼
<!--配置springmvc DispatcherServlet-->
<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:config/spring-mvc.xml</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
  <async-supported>true</async-supported>
</servlet>
復制代碼


      application-context.xml這個一般是采用非spring mvc架構,用來加載Application Context。

    如果直接采用SpringMVC,只需要把所有相關配置放到spring-mvc.xml中就好,一般spring mvc項目用不到多個serverlet。

開始進入正題。

(1)application-context.xml配置
    spring的核心配置文件的名字 叫做 applicationContext.xml,后期也可以通過配置文件中的配置修改名稱,在web.xml中進行如下配置:

 

 

 

1、首先介紹一下啟動一個項目的整體流程:
tomcat啟動一個WEB項目的時候,WEB容器會去讀取它的配置文件web.xml,讀取<listener>和<context-param>兩個結點。
 緊接着,容器創建一個ServletContext(servlet上下文,全局的),這個web項目的所有部分都將共享這個上下文。可以把ServletContext看成是一個Web應用的服務器端組件的共享內存,在ServletContext中可以存放共享數據。ServletContext對象是真正的一個全局對象,凡是web容器中的Servlet都可以訪問
 容器將<context-param>轉換為鍵值對,並交給servletContext。
  容器創建<listener>中的類實例,創建監聽器。  listener中ContextLoaderListener監聽器的作用就是啟動Web容器時,監聽servletContext對象的變化,獲取servletContext對象的<context-param>,來自動裝配ApplicationContext的配置信息。(即加載applicationContext.xml文件)
 

2、現在開始正式講解applicationContext.xml中的配置內容
1、掃描service層和dao層注解(spring中掃描service,然后再在SpringMVC中掃描controller中掃描controller。 因為如果Controller在主容器中進行掃描的話會掃描到原樣的service,那時service還沒有進行事務處理可能會引起事務失效)

 

     

    如圖所示:首先是開啟注解掃描,其次是設置注解掃描的包:com.dao和com.service

    A、  <context:annotation-config/>   : 自動簡化的完成相應bean的聲明。

           啟動spring的一些注解,主要包括:向 Spring 容器注冊如下4 個BeanPostProcessor。

 AutowiredAnnotationBeanPostProcessor       @Autowired注解
  CommonAnnotationBeanPostProcessor       @ Resource 、@ PostConstruct、@ PreDestroy
  PersistenceAnnotationBeanPostProcessor     @PersistenceContext注解
  RequiredAnnotationBeanPostProcessor 這     @Required的注解
       注冊這4個 BeanPostProcessor的作用,就是為了你的系統能夠識別相應的注解。

    <context:annotation-config/>的方式等價於以下的傳統方式:

          <bean class="org.springframework.beans.factory.annotation. AutowiredAnnotationBeanPostProcessor "/> 

   但是配置更加簡單,方便,不需要按照傳統的方式一條一條配置顯得有些繁瑣和沒有必要,於是spring給我們提供<context:annotation-config/>的簡化配置方式,自動幫你完成聲明。

 

    B、  設置使用注解的類所在的包 主要是dao層和service層,剔除controller層注解掃描

       

 

     注意,這部分主要是掃描項目中除了controller以外的其他層的注解。配置這部分的目的是在於掃描service包和dao包里面的類,只要有@Service或者@Repository就注冊成spring容器中的Bean,下次可以通過@Autowired直接注入。

          如果有B的配置,可以不需要A的配置,<context:component-scan base-package=”XX.XX”/> , 該配置項其實也包含了自動注入上述processor的功能,因此當使用 <context:component-scan/> 后,就可以將 <context:annotation-config/> 移除了。

 

2、配置數據庫相關內容(這部分內容可以單獨用一個spring-mybatis.xml進行配置,本項目沒有單獨進行配置,而是和applicaitonContext.xml文件一起配置的)

    配置db.properties文件-----》配置數據源(dataSource(可以采用數據庫連接池),可以配置多個數據源(如果有多個數據庫的話))---》配置spring+mybatis(Spring和Mybatis整合有兩種方式)----》配置事務(事務管理器、配置事務傳播特性、事務aop配置)

首先准備db.properties 配置文件

   1、所在項目文件夾的位置:

     

 

2、applicationContext.xml文件定位到dbconfig.properties文件

    

3、dbconfig.properties文件內容

4、在applicationContext.xml中配置數據源,后期需要可以在其中添加多個屬性配置。

 

5、配置spring+mybatis(主要是獲取sqlSession對象,通過MapperScannerConfigurer 自動裝配SqlSessionFactory 或 SqlSessionTemplate,MapperFactoryBean 創建的代理類實現了 UserMapper 接口,並且注入到應用程序中)

  創建SqlSessionFactory的過程:

 

①定義Configuration對象(包括數據源,事務,mapper文件資源以及影響數據庫行為屬性設置的settings) 
--> ②由Configuration對象創建一個SqlSessionFactoryBuilder對象
--> ③由SessionFactoryBuilder獲得SqlSessionFactory實例
--> ④由SqlSessionFactory實例獲得SqlSession實例,操作數據庫
      在 MyBatis 中,使用 SqlSessionFactoryBuilder創建SqlSessionFactory ,進而來創建 SqlSession。一旦你獲得一個 session 之后,你可以使用它來執行映射語句,提交或回滾連接,最后,當不再需要它的時候, 你可以關閉 session。 

      Mybatis社區自己開發了一個Mybatis-Spring用來滿足Mybatis用戶整合Spring的需求。使用 MyBatis-Spring 之后, 會使用SqlSessionFactoryBean來代替SqlSessionFactoryBuilder創建SqlSessionFactory,然后可以使用下面兩種方式使用sqlSession。1、SqlSessionTemplate;2、SqlSessionDaoSupport;上面做法沒問題,但就是在spring.xml中需要配置所有的dao層實現,把sqlSession或者sqlSessionFactory注入進去,可以使用MapperScannerConfigurer來解決這個問題,MapperScannerConfigurer幫我們自動裝配SqlSessionFactory 或 SqlSessionTemplate,因此不需要我們在applicationContext.xml文件中注入sqlSession或者sqlSessionFactory。

       SqlSessionFactoryBean、SqlSessionFactory、SqlSession、SqlSessionTemplate之間的關系。

 

 

         SqlSessionFactoryBean是生產SqlSessionFactory的一種工廠Bean;SqlSessionFactory是一種生產SqlSession的工廠;SqlSession是代表數據庫連接客戶端和數據庫Server之間的會話信息;SqlSessionTemplate是SqlSession的一個具體實現。

 

SqlSessionTemplate介紹:

     Mybatis-Spring提供了一種直接使用SqlSession的方式(一個實現了SqlSession接口的SqlSessionTemplate實現類)

                1、它是線程安全的,可以被多個Dao同時使用;

               2、 它跟Spring的事務進行了關聯,確保當前被使用的SqlSession是一個已經和Spring的事務進行綁定了的,而且它還可以自己管理Session的提交和關閉。

資料:https://blog.csdn.net/liuxiao723846/article/details/52424802

 

applicationContext.xml配置:Spring和Mybatis整合有兩種方式

方式一:需要mapper.xml文件,mapper文件里面寫sql語句,UserMapper接口類里面不寫sql語句

方式二:不需要mapper.xml文件,但是需要在UserMapper里面寫sql語句

詳細資料:https://www.cnblogs.com/ClassNotFoundException/p/6425558.html

 

5.1、需要配置MapperScannerConfigurer 自動掃描 將Mapper接口生成代理注入到Spring,這部分實現mapper.xml文件映射成mapper接口類的實現類,自動注入到spring中,這樣我們就不用寫mapper接口的實現類了。

 

 

原理:Mybatis在與Spring集成的時候可以配置MapperFactoryBean來生成Mapper接口的代理,MapperFactoryBean 創建的代理類實現了 UserMapper 接口,並且注入到應用程序中。 因為代理創建在運行時環境中(Runtime,譯者注) ,那么指定的映射器必須是一個接口,而 不是一個具體的實現類。MapperScannerConfigurer , 它 將 會 查 找 類 路 徑 下 的 映 射 器 並 自 動 將 它 們 創 建 成 MapperFactoryBean。(需要增加對MapperFactoryBean源碼的理解)

   注 意 , 沒 有 必 要 去 指 定 SqlSessionFactory 或 SqlSessionTemplate , 因 為 MapperScannerConfigurer 將會創建 MapperFactoryBean,之后自動裝配。但是,如果你使 用了一個 以上的 DataSource ,那 么自動 裝配可 能會失效 。這種 情況下 ,你可 以使用 sqlSessionFactoryBeanName 或 sqlSessionTemplateBeanName 屬性來設置正確的 bean 名 稱來使用。這就是它如何來配置的,注意 bean 的名稱是必須的,而不是 bean 的引用,因 此,value 屬性在這里替代通常的 ref。

資料詳解:https://www.cnblogs.com/daxin/p/3545040.html

 

6、配置事務管理器(聲明式事務:用面向切片編程AOP的思想,來管理事務;編程式:TransactionTemplate)

復制代碼
<?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:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:task="http://www.springframework.org/schema/task" xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
    http://www.springframework.org/schema/context   
    http://www.springframework.org/schema/context/spring-context-4.1.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx-4.1.xsd
    http://www.springframework.org/schema/task 
    http://www.springframework.org/schema/task/spring-task-4.1.xsd
    http://www.springframework.org/schema/aop 
    http://www.springframework.org/schema/aop/spring-aop-4.1.xsd"
       default-lazy-init="false">
    <!-- 對dataSource 數據源進行事務管理 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!-- 事務管理 通知,對不同的方法進行不同的事務管理 -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <!-- 對insert,create,update,modify,delete,remove 開頭的方法進行事務管理,只要有異常就回滾 -->
            <tx:method name="insert*" propagation="REQUIRED" rollback-for="java.lang.Throwable" read-only="false"/>
            <tx:method name="add*" propagation="REQUIRED" rollback-for="java.lang.Throwable" read-only="false"/>
            <tx:method name="create*" propagation="REQUIRED" rollback-for="java.lang.Throwable" read-only="false"/>
            <tx:method name="update*" propagation="REQUIRED" rollback-for="java.lang.Throwable" read-only="false"/>
            <tx:method name="modify*" propagation="REQUIRED" rollback-for="java.lang.Throwable" read-only="false"/>
            <tx:method name="delete*" propagation="REQUIRED" rollback-for="java.lang.Throwable" read-only="false"/>
            <tx:method name="remove*" propagation="REQUIRED" rollback-for="java.lang.Throwable" read-only="false"/>
            <!-- find,get,select,count開頭的方法,開啟只讀,提高數據庫訪問性能 -->
            <tx:method name="find*" read-only="true"/>
            <tx:method name="get*" read-only="true"/>
            <tx:method name="select*" read-only="true"/>
            <tx:method name="count*" read-only="true"/>
            <!-- 對其他方法 使用默認的事務管理 -->
            <tx:method name="*"/>
        </tx:attributes>
    </tx:advice>

    <!-- 事務 aop 配置     
    <aop:pointcut>切入點    <aop:advice>需要注入的方法   <aop:advisor> 適配器,把注入的方法注入切入點的位置,是連接pointcut跟advice的工具-->

    <aop:config>
        <aop:pointcut id="serviceMethods" expression="execution(public * com.service..*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethods"/>
    </aop:config>

    <!-- 配置使Spring采用CGLIB代理 --><!-- 開啟基於@AspectJ切面的注解處理器 -->
    <aop:aspectj-autoproxy proxy-target-class="true"/>

    <!-- 配置 Annotation 驅動,掃描@Transactional注解的類定義事務  -->
    <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
</beans>
復制代碼


 事務管理的兩種方式:    

       事務管理對於企業應用而言,是至關重要的,即使出現異常情況,他也可以保證數據的一致性。事務的管理方式有兩種:1、支持編程式事務管理‘2、支持聲明式事務管理方式。編程式事務管理是使用:TransactionTemplate,聲明式事務管理建立在AOP之上,其本質是對方法前后進行攔截,然后在目標方法開始之前創建或者加入一個事務,在執行完目標方法之后,根據執行情況提交或者回滾事務。聲明式事務的優點是可以基於注解@Transactional來管理,很方便,但是不足之處在於粒度較大,只能作用到方法級別,不能像編程式事務那樣,做到代碼塊級別。’

      詳情介紹:https://www.cnblogs.com/sword-successful/p/7274929.html

 

(2)sping-mvc.xml的配置
       web項目啟動時,讀取web.xml配置文件,首先解析的是applicationContext.xml文件,其次才是sping-mvc.xml文件,sping-mvc.xml文件中主要的工作是:啟動注解、掃描controller包注解;靜態資源映射;視圖解析(defaultViewResolver);文件上傳(multipartResolver);返回消息json配置。

 1.自動掃描

<!-- 自動掃描該包,使SpringMVC認為包下用了@controller注解的類是控制器 -->
<context:component-scan base-package="com.javen.controller" />

2.注解驅動

<!-- 擴充了注解驅動,可以將請求參數綁定到控制參數-->
<mvc:annotation-driven />

3.靜態資源處理

<!-- 靜態資源處理 css js images -->
<mvc:resources location="/resources/**" mapping="/resource/"/>

4.避免IE執行AJAX時,返回JSON出現下載文件

復制代碼
    <!--避免IE執行AJAX時,返回JSON出現下載文件 -->
    <bean id="mappingJackson2HttpMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
        <property name="supportedMediaTypes">
            <list>
                <value>text/html;charset=UTF-8</value>
                <value>text/json;charset=UTF-8</value>
                <value>application/json;charset=UTF-8</value>
            </list>
        </property>
    </bean>
復制代碼

5.啟動SpringMVC的注解功能,完成請求和注解POJO的映射

復制代碼
    <!-- 啟動SpringMVC的注解功能,完成請求和注解POJO的映射 -->
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
        <property name="messageConverters">
            <list>
                <ref bean="mappingJackson2HttpMessageConverter"/>    <!-- JSON轉換器 -->
            </list>
        </property>
    </bean>
復制代碼

6.配置文件上傳

復制代碼
    <!-- 配置文件上傳,如果沒有使用文件上傳可以不用配置,當然如果不配,那么配置文件中也不必引入上傳組件包 -->
    <bean id="multipartResolver"
          class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!-- 默認編碼 -->
        <property name="defaultEncoding" value="utf-8"/>
        <!-- 上傳文件最大值 -->
        <property name="maxUploadSize" value="10485760000"/>
        <!-- 內存中的最大值 -->
        <property name="maxInMemorySize" value="40960"/>
        <!-- 啟用是為了推遲文件解析,以便捕獲文件大小異常 -->
        <property name="resolveLazily" value="true"/>
    </bean>
復制代碼

7.配置viewResolver視圖解析

復制代碼
    <!-- 配置viewResolver。可以用多個viewResolver。使用order屬性排序。InternalResourceViewResolver 放在最后 -->
    <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
        <property name="order" value="1"></property>
        <property name="mediaTypes">
            <map>
                <!-- 告訴視圖解析器,返回的類型為json格式 -->
                <entry key="json" value="application/json" />
                <entry key="xml" value="application/xml" />
                <entry key="htm" value="text/htm" />
            </map>
        </property>
        <property name="defaultViews">
            <list>
                <!-- ModelAndView里的數據變成JSON -->
                <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />
            </list>
        </property>
        <property name="ignoreAcceptHeader" value="true"></property>
    </bean>
復制代碼

8.定義跳轉的文件的前后綴 ,視圖模式配置

    <!-- 定義跳轉的文件的前后綴 ,視圖模式配置-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!-- 這里的配置我的理解是自動給后面action的方法return的字符串加上前綴和后綴,變成一個 可用的url地址 -->
        <property name="prefix" value="/WEB-INF/jsp/" />
        <property name="suffix" value=".jsp" />
    </bean>


免責聲明!

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



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