SPRINGMVC多數據鏈接Demo

有的時候項目中可能要從另外一個系統取數據,兩種方式

一、接口

SpringMVC簡介
 
 一 流程介紹
1.角色劃分
前端控制器(DispatcherServlet)、請求到處理器映射(HandlerMapping)、處理器適配器(HandlerAdapter)、視圖解析器(ViewResolver)、處理器或頁面控制器(Controller)、驗證器(Validator)、命令對象(Command請求參數綁定到的對象就叫命令對象)、表單對象(Form Object提供給表單展示和提交到的對象就叫表單對象)。
2.流程圖

3.具體步驟:
(1)首先用戶發送請求——>DispatcherServlet,前端控制器收到請求後自己不進行處理,而是委託給其他的解析器進行處理,作爲統一訪問點,進行全局的流程控制;
(2)DispatcherServlet——>HandlerMapping, HandlerMapping將會把請求映射爲HandlerExecutionChain對象(包含一個Handler處理器(頁面控制器)對象、多個HandlerInterceptor攔截器)對象,通過這種策略模式,很容易添加新的映射策略;
(3)DispatcherServlet——>HandlerAdapter,HandlerAdapter將會把處理器包裝爲適配器,從而支持多種類型的處理器,即適配器設計模式的應用,從而很容易支持很多類型的處理器;
(4)HandlerAdapter——>處理器功能處理方法的調用,HandlerAdapter將會根據適配的結果調用真正的處理器的功能處理方法,完成功能處理;並返回一個ModelAndView對象(包含模型數據、邏輯視圖名);
(5)ModelAndView的邏輯視圖名——> ViewResolver, ViewResolver將把邏輯視圖名解析爲具體的View,通過這種策略模式,很容易更換其他視圖技術;
(6)View——>渲染,View會根據傳進來的Model模型數據進行渲染,此處的Model實際是一個Map數據結構,因此很容易支持其他視圖技術;
(7)返回控制權給DispatcherServlet,由DispatcherServlet返回響應給用戶,到此一個流程結束。

 

二 重要的接口及其實現

1.DispatcherServlet部分

DispatcherServlet是一個Servlet,所以可以配置多個DispatcherServlet。
DispatcherServlet是前置控制器,配置在web.xml文件中的。攔截匹配的請求,Servlet攔截匹配規則要自已定義,把攔截下來的請求,依據某某規則分發到目標Controller(我們寫的Action)來處理。
“某某規則”:是根據你使用了哪個HandlerMapping接口的實現類的不同而不同。
xml代碼示例1:

複製代碼
<web-app>  
        <servlet>  
            <servlet-name>example</servlet-name>  
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
            <load-on-startup>1</load-on-startup>  
        </servlet>  
        <servlet-mapping>  
            <servlet-name>example</servlet-name>  
            <url-pattern>*.form</url-pattern>  
        </servlet-mapping>  
    </web-app>  
複製代碼

<load-on-startup>1</load-on-startup>是啓動順序,讓這個Servlet隨Servlet容器一起啓動。
 <url-pattern>*.form</url-pattern> 會攔截*.form結尾的請求。    
<servlet-name>example</servlet-name>這個Servlet的名字是example,可以有多個DispatcherServlet,是通過名字來區分的。每一個DispatcherServlet有自己的WebApplicationContext上下文對象。同時保存的ServletContext中和Request對象中。    
在DispatcherServlet的初始化過程中,框架會在web應用的 WEB-INF文件夾下尋找名爲[servlet-name]-servlet.xml 的配置文件,生成文件中定義的bean。

xml代碼示例2:

複製代碼
<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*:/springMVC.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>
複製代碼

指明瞭配置文件的文件名,不使用默認配置文件名,而使用springMVC.xml配置文件。
其中<param-value>**.xml</param-value> 這裏可以使用多種寫法
(1)不寫,使用默認值:/WEB-INF/<servlet-name>-servlet.xml
(2)<param-value>/WEB-INF/classes/springMVC.xml</param-value>
(3)<param-value>classpath*:springMVC-mvc.xml</param-value>
(4)多個值用逗號分隔    

 

2.配置HandlerMapping、HandlerAdapter
在springMVC.xml中的配置爲:

<!-- HandlerMapping -->  
    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>        
    <!-- HandlerAdapter -->  
    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>  

BeanNameUrlHandlerMapping:表示將請求的URL和Bean名字映射,如URL爲 “上下文/hello”,則Spring配置文件必須有一個名字爲“/hello”的Bean,上下文默認忽略。
SimpleControllerHandlerAdapter:表示所有實現了org.springframework.web.servlet.mvc.Controller接口的Bean可以作爲Spring Web MVC中的處理器。如果需要其他類型的處理器可以通過實現HadlerAdapter來解決。    

 

3.配置ViewResolver

<!-- ViewResolver -->  
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">  
    <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>  
    <property name="prefix" value="/WEB-INF/jsp/"/>  
    <property name="suffix" value=".jsp"/>  
</bean>

InternalResourceViewResolver:用於支持Servlet、JSP視圖解析;
viewClass:JstlView表示JSP模板頁面需要使用JSTL標籤庫,classpath中必須包含jstl的相關jar包;
prefix和suffix:查找視圖頁面的前綴和後綴(前綴[邏輯視圖名]後綴),比如傳進來的邏輯視圖名爲hello,則該該jsp視圖頁面應該存放在“WEB-INF/jsp/hello.jsp”; 

 

一個springMVC-mvc.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:tx="http://www.springframework.org/schema/tx"  
        xmlns:context="http://www.springframework.org/schema/context"    
        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.0.xsd   
        http://www.springframework.org/schema/tx   
        http://www.springframework.org/schema/tx/spring-tx-3.0.xsd  
        http://www.springframework.org/schema/context  
        http://www.springframework.org/schema/context/spring-context-3.0.xsd  
        http://www.springframework.org/schema/mvc  
        http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">  
      
      
        <!-- 自動掃描的包名 -->  
        <context:component-scan base-package="com.app,com.core,JUnit4" ></context:component-scan>  
          
        <!-- 默認的註解映射的支持 -->  
        <mvc:annotation-driven />  
          
        <!-- 視圖解釋類 -->  
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">  
            <property name="prefix" value="/WEB-INF/jsp/"/>  
            <property name="suffix" value=".jsp"/><!--可爲空,方便實現自已的依據擴展名來選擇視圖解釋類的邏輯  -->  
            <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />  
        </bean>  
          
        <!-- 攔截器 -->  
        <mvc:interceptors>  
            <bean class="com.core.mvc.MyInteceptor" />  
        </mvc:interceptors>       
          
        <!-- 對靜態資源文件的訪問  方案一 (二選一) -->  
        <mvc:default-servlet-handler/>  
          
        <!-- 對靜態資源文件的訪問  方案二 (二選一)-->  
        <mvc:resources mapping="/images/**" location="/images/" cache-period="31556926"/>  
        <mvc:resources mapping="/js/**" location="/js/" cache-period="31556926"/>  
        <mvc:resources mapping="/css/**" location="/css/" cache-period="31556926"/>  
      
    </beans>   
複製代碼

注意:
(1)這裏使用了<mvc:annotation-driven/>註解,這是一種簡寫形式,完全可以手動配置替代這種簡寫形式,簡寫形式可以讓初學都快速應用默認配置方案。<mvc:annotation-driven/> 會自動註冊DefaultAnnotationHandlerMapping與AnnotationMethodHandlerAdapter兩個bean,是springMVC爲@Controllers分發請求所必須的。並提供了:數據綁定支持,@NumberFormatannotation支持,@DateTimeFormat支持,@Valid支持,讀寫XML的支持(JAXB),讀寫JSON的支持(Jackson)。
(2)<mvc:interceptors/>是一種簡寫形式。我們可以配置多個HandlerMapping。<mvc:interceptors/>會爲每一個HandlerMapping,注入一個攔截器。其實我們也可以手動配置爲每個HandlerMapping注入一個攔截器。
(3)<mvc:default-servlet-handler/> 使用默認的Servlet來響應靜態文件。
(4)<mvc:resources mapping="/images/**" location="/images/" cache-period="31556926"/>
匹配URL /images/**的URL被當做靜態資源,由Spring讀出到內存中再響應http。

 

4.訪問靜態文件
如何你的DispatcherServlet攔截"*.do"這樣的有後綴的URL,就不存在訪問不到靜態資源的問題。
如果你的DispatcherServlet攔截"/",爲了實現REST風格,攔截了所有的請求,那麼同時對*.js,*.jpg等靜態文件的訪問也就被攔截了。
方案一:激活Tomcat的defaultServlet來處理靜態文件

複製代碼
<servlet-mapping>   
    <servlet-name>default</servlet-name>  
    <url-pattern>*.jpg</url-pattern>     
</servlet-mapping>    
<servlet-mapping>       
    <servlet-name>default</servlet-name>    
    <url-pattern>*.js</url-pattern>    
</servlet-mapping>    
<servlet-mapping>        
    <servlet-name>default</servlet-name>       
    <url-pattern>*.css</url-pattern>      
</servlet-mapping>    
複製代碼

要配置多個,每種文件配置一個。
要寫在DispatcherServlet的前面, 讓 defaultServlet先攔截請求,這樣請求就不會進入Spring了,應該性能是最好的吧。

方案二: 在spring3.0.4以後版本提供了mvc:resources
<mvc:resources mapping="/images/**" location="/images/" />  
/images/**映射到ResourceHttpRequestHandler進行處理,location指定靜態資源的位置.可以是web application根目錄下、jar包裏面,這樣可以把靜態資源壓縮到jar包中。cache-period 可以使得靜態資源進行web cache
使用<mvc:resources/>元素,把mapping的URI註冊到SimpleUrlHandlerMapping的urlMap中,key爲mapping的URI pattern值,而value爲ResourceHttpRequestHandler,
這樣就巧妙的把對靜態資源的訪問由HandlerMapping轉到ResourceHttpRequestHandler處理並返回,所以就支持classpath目錄,jar包內靜態資源的訪問。

 

5.攔截器
自定義一個攔截器,要實現HandlerInterceptor接口

複製代碼
public class MyInterceptor implements HandlerInterceptor {
 
    @Override
    public void afterCompletion(HttpServletRequest arg0,
            HttpServletResponse arg1, Object arg2, Exception arg3)
            throws Exception {
        System.out.println("afterCompletion");
    }
 
    @Override
    public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,
            Object arg2, ModelAndView arg3) throws Exception {
        System.out.println("postHandle");
    }
 
    @Override
    public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1,
            Object arg2) throws Exception {
        System.out.println("preHandle");
        return true;
    }
 
}
複製代碼

在spring MVC的配置文件中配置有三種方法:
方案一,(近似)總攔截器,攔截所有url

<mvc:interceptors>  
    <bean class="com.app.mvc.MyInteceptor" />  
</mvc:interceptors>

<mvc:interceptors/>會爲每一個HandlerMapping,注入一個攔截器。總有一個HandlerMapping是可以找到處理器的,最多也只找到一個處理器,所以這個攔截器總會被執行的。起到了總攔截器的作用。如果是REST風格的URL,靜態資源也會被攔截。
方案二, (近似) 總攔截器, 攔截匹配的URL

<mvc:interceptors >    
      <mvc:interceptor>    
            <mvc:mapping path="/user/*" /> <!-- /user/*  -->    
            <bean class="com.mvc.MyInteceptor"></bean>    
        </mvc:interceptor>    
    </mvc:interceptors>  

就是比 方案一多了一個URL匹配。如果是REST風格的URL,靜態資源也會被攔截。
方案三,HandlerMappint上的攔截器

複製代碼
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">       
     <property name="interceptors">       
         <list>       
             <bean class="com.mvc.MyInteceptor"></bean>      
         </list>       
     </property>       
 </bean>   
複製代碼

如果是REST風格的URL,靜態資源就不會被攔截。因爲我們精準的注入了攔截器。
如果使用了<mvc:annotation-driven />, 它會自動註冊DefaultAnnotationHandlerMapping 與AnnotationMethodHandlerAdapter 這兩個bean,所以就沒有機會再給它注入interceptors屬性,就無法指定攔截器。
當然我們可以通過人工配置上面的兩個Bean,不使用 <mvc:annotation-driven />,就可以 給interceptors屬性 注入攔截器了。


二、配置多個數據源切換訪問

<1>:這是數據源和事務掃描注入的配置 訪問多個數據源只需要建立多個數據源和事務這一套配置文件

這是第一個數據源

[html] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
  4.     xmlns:context="http://www.springframework.org/schema/context"  
  5.     xmlns:jdbc="http://www.springframework.org/schema/jdbc"   
  6.     xmlns:jee="http://www.springframework.org/schema/jee"  
  7.     xmlns:tx="http://www.springframework.org/schema/tx"   
  8.     xmlns:aop="http://www.springframework.org/schema/aop"  
  9.     xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"  
  10.     xsi:schemaLocation="  
  11.         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd  
  12.         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd  
  13.         http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd  
  14.         http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd  
  15.         http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd  
  16.         http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd  
  17.         http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd  
  18.         http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"  
  19.     default-lazy-init="true">  
  20.   
  21.     <description>Spring公共配置 </description>  
  22.       
  23.     <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">  
  24.         <property name="locations">  
  25.             <list>  
  26.                 <value>classpath:resources.properties</value>  
  27.                 <!--  <value>classpath:memcached.properties</value> -->  
  28.             </list>  
  29.         </property>  
  30.     </bean>  
  31.       
  32.     <!-- dubbo配置 -->  
  33.     <!-- <dubbo:application name="xaUserRegPro" />  
  34.     <dubbo:registry address="multicast://" />  
  35.     <dubbo:reference id="userRegProService" interface="com.xinnet.xa.service.UserRegProService"  timeout="6000"/> -->  
  36.       
  37.  <!-- **************** druid 監控連接池配置 ***************** -->  
  38.     <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">  
  39.           
  40.         <!-- 基本屬性 url、user、password -->  
  41.         <property name="url" value="${url}" />  
  42.         <property name="username" value="${username}" />  
  43.         <property name="password" value="${password}" />  
  44.           
  45.         <!-- 配置初始化大小、最小、最大 -->  
  46.         <property name="initialSize" value="${initialSize}" />  
  47.         <property name="minIdle" value="${minIdle}" />  
  48.         <property name="maxActive" value="${maxActive}" />  
  49.           
  50.         <!-- 配置獲取連接等待超時的時間 -->  
  51.         <property name="maxWait" value="${maxWait}" />  
  52.           
  53.         <!-- 配置間隔多久才進行一次檢測,檢測需要關閉的空閒連接,單位是毫秒 -->  
  54.         <property name="timeBetweenEvictionRunsMillis" value="60000" />  
  55.           
  56.         <!-- 配置一個連接在池中最小生存的時間,單位是毫秒 -->  
  57.         <property name="minEvictableIdleTimeMillis" value="300000" />  
  58.         <property name="validationQuery" value="SELECT 'x'" />  
  59.         <property name="testWhileIdle" value="true" />  
  60.         <property name="testOnBorrow" value="false" />  
  61.         <property name="testOnReturn" value="false" />  
  62.           
  63.         <!-- 打開PSCache,並且指定每個連接上PSCache的大小  -->  
  64.         <!-- 如果用Oracle,則把poolPreparedStatements配置爲true,mysql可以配置爲false。分庫分表較多的數據庫,建議配置爲false -->  
  65.         <property name="poolPreparedStatements" value="${poolPreparedStatements}" />  
  66.         <property name="maxPoolPreparedStatementPerConnectionSize" value="20" />  
  67.           
  68.         <!-- 對泄漏的連接 自動關閉 -->  
  69.         <property name="removeAbandoned" value="${removeAbandoned}" /> <!-- 打開removeAbandoned功能 -->  
  70.         <property name="removeAbandonedTimeout" value="${removeAbandonedTimeout}" /> <!-- 1800秒,也就是30分鐘 -->  
  71.         <property name="logAbandoned" value="${logAbandoned}" /> <!-- 關閉abanded連接時輸出錯誤日誌 -->  
  72.           
  73.         <!-- 配置監控統計攔截的filters -->  
  74.         <property name="filters" value="mergeStat" />  
  75.         <!--  <property name="filters" value="stat" /> -->  
  76.         <!-- 慢日誌查詢  缺省爲3秒  修改爲10秒 10000 -->  
  77.         <property name="connectionProperties" value="druid.stat.slowSqlMillis=5000" />  
  78.           
  79.         <!-- DruidDataSource各自獨立 , 支持配置公用監控數據 -->  
  80.         <!-- <property name="useGloalDataSourceStat" value="true" /> -->  
  81.     </bean>  
  82.       
  83.     <!-- druid 監控  spring  -->  
  84.     <bean id="druid-stat-interceptor" class="com.alibaba.druid.support.spring.stat.DruidStatInterceptor"/>  
  85.     <bean id="druid-stat-pointcut" class="org.springframework.aop.support.JdkRegexpMethodPointcut" scope="prototype">  
  86.         <property name="patterns">  
  87.             <list>  
  88.                 <value>com.xinnet.*.service.*</value>  
  89.             </list>  
  90.         </property>  
  91.     </bean>  
  92.     <aop:config>  
  93.         <aop:advisor advice-ref="druid-stat-interceptor" pointcut-ref="druid-stat-pointcut" />  
  94.     </aop:config>  
  95.       
  96.     <!-- MyBatis Mapper.XMl 配置 -->  
  97.     <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">  
  98.         <property name="dataSource" ref="dataSource" />  
  99.         <property name="configLocation" value="classpath:config/mybatis.xml" />  
  100.         <property name="mapperLocations">  
  101.             <list>  
  102.             <!-- 自動匹配Mapper映射文件  -->  
  103.                 <value>classpath:mapper/**/*-mapper.xml</value>  
  104.             </list>  
  105.         </property>  
  106.         <!-- 添加插件 -->  
  107.         <property name="plugins">  
  108.             <array>  
  109.                 <ref bean="pagePlugin" />  
  110.             </array>  
  111.         </property>  
  112.     </bean>  
  113.       
  114.     <!-- 支持文件上傳相關 -->  
  115.     <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>  
  116.       
  117.     <!-- 分頁插件,根據方言自動添加分頁信息,默認要求 -->  
  118.     <bean id="pagePlugin" class="com.xinnet.core.mybatis.plugin.PagePlugin">  
  119.         <property name="properties">  
  120.             <props>  
  121.                 <prop key="dialect">com.xinnet.core.mybatis.dialet.MySQLDialect</prop>  
  122.                 <prop key="pageSqlId">.*query.*</prop>  
  123.             </props>  
  124.         </property>  
  125.     </bean>  
  126.     <!-- redis客戶端 -->  
  127.      <!-- jedis pool配置  -->    
  128.     <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">    
  129.         <property name="maxActive" value="${redis.maxActive}" />    
  130.         <property name="maxIdle" value="${redis.maxIdle}" />    
  131.         <property name="maxWait" value="${redis.maxWait}" />    
  132.         <property name="testOnBorrow" value="${redis.testOnBorrow}" />    
  133.     </bean>    
  134.       
  135.     <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">    
  136.         <property name="usePool" value="true"></property>    
  137.         <property name="hostName" value="${redis.host}" />    
  138.         <property name="port" value="${redis.port}" />    
  139.         <property name="password" value="${redis.pass}" />    
  140.         <property name="timeout" value="${redis.timeout}" />    
  141.         <property name="database" value="${redis.default.db}"></property>    
  142.         <constructor-arg index="0" ref="jedisPoolConfig" />    
  143.     </bean>    
  144.     <bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">    
  145.         <property name="connectionFactory" ref="jedisConnectionFactory" />    
  146.     </bean>  
  147.      
  148.     <!-- ***************事務配置************** -->  
  149.     <tx:annotation-driven transaction-manager="transactionManager"/>  
  150.     <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
  151.         <property name="dataSource" ref="dataSource" />  
  152.     </bean>  
  153.     <aop:config>    
  154.              <aop:advisor pointcut="execution(* com.xinnet..service..*.*(..))"  advice-ref="txAdvice" />    
  155.     </aop:config>    
  156.     <tx:advice id="txAdvice" transaction-manager="transactionManager">    
  157.         <tx:attributes>    
  158.             <tx:method name="get*" read-only="true" />    
  159.             <tx:method name="query*" read-only="true" />    
  160.             <tx:method name="find*" read-only="true" />    
  161.             <tx:method name="load*" read-only="true" />  
  162.             <tx:method name="select*" read-only="true" />   
  163.             <tx:method name="count*" read-only="true" />    
  164.             <tx:method name="search*" read-only="true" />    
  165.             <tx:method name="list*" read-only="true" />    
  166.             <tx:method name="*" propagation="REQUIRED" rollback-for="Exception" />    
  167.         </tx:attributes>    
  168.     </tx:advice>    
  169.     <aop:aspectj-autoproxy proxy-target-class="true"/>    
  170.     <!-- 開啓註解事務 只對當前配置文件有效 -->  
  171.       
  172.     <!-- 掃描註解Bean -->  
  173.     <context:component-scan base-package="com.xinnet">  
  174.         <context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"/>    
  175.         <context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/>  
  176.         <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>  
  177.     </context:component-scan>  
  178.      <!-- 隱式地向 Spring 容器註冊 -->  
  179.     <context:annotation-config/>   
  180.       
  181. </beans>  


<2>這是第二個數據源 和第一個數據源一樣 需要有事務 掃描註解
 不同的是數據源的 url  username 和password 用的是第二個數據源的連接  用戶名和密碼


[html] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
  4.     xmlns:context="http://www.springframework.org/schema/context"  
  5.     xmlns:jdbc="http://www.springframework.org/schema/jdbc"   
  6.     xmlns:jee="http://www.springframework.org/schema/jee"  
  7.     xmlns:tx="http://www.springframework.org/schema/tx"   
  8.     xmlns:aop="http://www.springframework.org/schema/aop"  
  9.     xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"  
  10.     xsi:schemaLocation="  
  11.         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd  
  12.         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd  
  13.         http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd  
  14.         http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd  
  15.         http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd  
  16.         http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd  
  17.         http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd  
  18.         http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"  
  19.     default-lazy-init="true">  
  20.   
  21.     <description>Spring公共配置 </description>  
  22.       
  23.     <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">  
  24.         <property name="locations">  
  25.             <list>  
  26.                 <value>classpath:resources.properties</value>  
  27.                 <!--  <value>classpath:memcached.properties</value> -->  
  28.             </list>  
  29.         </property>  
  30.     </bean>  
  31.       
  32.  <!-- **************** druid 監控連接池配置 *****************  -->  
  33.     <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">  
  34.           
  35.         <!-- 基本屬性 url、user、password -->  
  36.         <property name="url" value="${url2}" />  
  37.         <property name="username" value="${username2}" />  
  38.         <property name="password" value="${password2}" />  
  39.           
  40.         <!-- 配置初始化大小、最小、最大 -->  
  41.         <property name="initialSize" value="${initialSize}" />  
  42.         <property name="minIdle" value="${minIdle}" />  
  43.         <property name="maxActive" value="${maxActive}" />  
  44.           
  45.         <!-- 配置獲取連接等待超時的時間 -->  
  46.         <property name="maxWait" value="${maxWait}" />  
  47.           
  48.         <!-- 配置間隔多久才進行一次檢測,檢測需要關閉的空閒連接,單位是毫秒 -->  
  49.         <property name="timeBetweenEvictionRunsMillis" value="60000" />  
  50.           
  51.         <!-- 配置一個連接在池中最小生存的時間,單位是毫秒 -->  
  52.         <property name="minEvictableIdleTimeMillis" value="300000" />  
  53.         <property name="validationQuery" value="SELECT 'x'" />  
  54.         <property name="testWhileIdle" value="true" />  
  55.         <property name="testOnBorrow" value="false" />  
  56.         <property name="testOnReturn" value="false" />  
  57.           
  58.         <!-- 打開PSCache,並且指定每個連接上PSCache的大小  -->  
  59.         <!-- 如果用Oracle,則把poolPreparedStatements配置爲true,mysql可以配置爲false。分庫分表較多的數據庫,建議配置爲false -->  
  60.         <property name="poolPreparedStatements" value="${poolPreparedStatements}" />  
  61.         <property name="maxPoolPreparedStatementPerConnectionSize" value="20" />  
  62.           
  63.         <!-- 對泄漏的連接 自動關閉 -->  
  64.         <property name="removeAbandoned" value="${removeAbandoned}" /> <!-- 打開removeAbandoned功能 -->  
  65.         <property name="removeAbandonedTimeout" value="${removeAbandonedTimeout}" /> <!-- 1800秒,也就是30分鐘 -->  
  66.         <property name="logAbandoned" value="${logAbandoned}" /> <!-- 關閉abanded連接時輸出錯誤日誌 -->  
  67.           
  68.         <!-- 配置監控統計攔截的filters -->  
  69.         <property name="filters" value="mergeStat" />  
  70.         <!--  <property name="filters" value="stat" /> -->  
  71.         <!-- 慢日誌查詢  缺省爲3秒  修改爲10秒 10000 -->  
  72.         <property name="connectionProperties" value="druid.stat.slowSqlMillis=5000" />  
  73.           
  74.         <!-- DruidDataSource各自獨立 , 支持配置公用監控數據 -->  
  75.         <!-- <property name="useGloalDataSourceStat" value="true" /> -->  
  76.     </bean>  
  77.       
  78.     <!-- druid 監控  spring  -->  
  79.     <bean id="druid-stat-interceptor" class="com.alibaba.druid.support.spring.stat.DruidStatInterceptor"/>  
  80.     <bean id="druid-stat-pointcut" class="org.springframework.aop.support.JdkRegexpMethodPointcut" scope="prototype">  
  81.         <property name="patterns">  
  82.             <list>  
  83.                 <value>com.xinnet.*.service.*</value>  
  84.             </list>  
  85.         </property>  
  86.     </bean>  
  87.     <aop:config>  
  88.         <aop:advisor advice-ref="druid-stat-interceptor" pointcut-ref="druid-stat-pointcut" />  
  89.     </aop:config>  
  90.       
  91.     <!-- MyBatis Mapper.XMl 配置 -->  
  92.     <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">  
  93.         <property name="dataSource" ref="dataSource" />  
  94.         <property name="configLocation" value="classpath:config/mybatis.xml" />  
  95.         <property name="mapperLocations">  
  96.             <list>  
  97.             <!-- 自動匹配Mapper映射文件  -->  
  98.                 <value>classpath:mapper/**/*-mapper.xml</value>  
  99.             </list>  
  100.         </property>  
  101.         <!-- 添加插件 -->  
  102.         <property name="plugins">  
  103.             <array>  
  104.                 <ref bean="pagePlugin" />  
  105.             </array>  
  106.         </property>  
  107.     </bean>  
  108.       
  109.     <!-- 支持文件上傳相關 -->  
  110.     <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>  
  111.       
  112.     <!-- 分頁插件,根據方言自動添加分頁信息,默認要求 -->  
  113.     <bean id="pagePlugin" class="com.xinnet.core.mybatis.plugin.PagePlugin">  
  114.         <property name="properties">  
  115.             <props>  
  116.                 <prop key="dialect">com.xinnet.core.mybatis.dialet.MySQLDialect</prop>  
  117.                 <prop key="pageSqlId">.*query.*</prop>  
  118.             </props>  
  119.         </property>  
  120.     </bean>  
  121.     <!-- redis客戶端 -->  
  122.      <!-- jedis pool配置  -->    
  123.     <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">    
  124.         <property name="maxActive" value="${redis.maxActive}" />    
  125.         <property name="maxIdle" value="${redis.maxIdle}" />    
  126.         <property name="maxWait" value="${redis.maxWait}" />    
  127.         <property name="testOnBorrow" value="${redis.testOnBorrow}" />    
  128.     </bean>    
  129.       
  130.     <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">    
  131.         <property name="usePool" value="true"></property>    
  132.         <property name="hostName" value="${redis.host}" />    
  133.         <property name="port" value="${redis.port}" />    
  134.         <property name="password" value="${redis.pass}" />    
  135.         <property name="timeout" value="${redis.timeout}" />    
  136.         <property name="database" value="${redis.default.db}"></property>    
  137.         <constructor-arg index="0" ref="jedisPoolConfig" />    
  138.     </bean>    
  139.     <bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">    
  140.         <property name="connectionFactory" ref="jedisConnectionFactory" />    
  141.     </bean>  
  142.      
  143.     <!-- ***************事務配置************** -->  
  144.     <tx:annotation-driven transaction-manager="transactionManager"/>  
  145.     <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
  146.         <property name="dataSource" ref="dataSource" />  
  147.     </bean>  
  148.     <aop:config>    
  149.              <aop:advisor pointcut="execution(* com.xinnet..service..*.*(..))"  advice-ref="txAdvice" />    
  150.     </aop:config>    
  151.     <tx:advice id="txAdvice" transaction-manager="transactionManager">    
  152.         <tx:attributes>    
  153.             <tx:method name="get*" read-only="true" />    
  154.             <tx:method name="query*" read-only="true" />    
  155.             <tx:method name="find*" read-only="true" />    
  156.             <tx:method name="load*" read-only="true" />  
  157.             <tx:method name="select*" read-only="true" />   
  158.             <tx:method name="count*" read-only="true" />    
  159.             <tx:method name="search*" read-only="true" />    
  160.             <tx:method name="list*" read-only="true" />    
  161.             <tx:method name="*" propagation="REQUIRED" rollback-for="Exception" />    
  162.         </tx:attributes>    
  163.     </tx:advice>    
  164.     <aop:aspectj-autoproxy proxy-target-class="true"/>    
  165.     <!-- 開啓註解事務 只對當前配置文件有效 -->  
  166.       
  167.     <!-- 掃描註解Bean -->  
  168.     <context:component-scan base-package="com.xinnet">  
  169.         <context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"/>    
  170.         <context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/>  
  171.         <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>  
  172.     </context:component-scan>  
  173.      <!-- 隱式地向 Spring 容器註冊 -->  
  174.     <context:annotation-config/>   
  175.       
  176. </beans>  

<3>這個時候就可以用兩個數據源進行切換注入 從而使用不同數據源的service

這是service裏面的方法 該怎麼寫就是怎麼寫 該怎麼註解就怎麼註解 不用做特殊的步驟 

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. @Service("partyService")  
  2. public class PartyServiceImpl implements PartyService {  
  3.   
  4.     @Autowired  
  5.     private PartyDao partyDao;  
  6.       
  7.     @Override  
  8.     public List<Emp> getAllEmp() throws SQLException {  
  9.         return partyDao.getAllEmp();  
  10.     }  
  11.   
  12. }  
Dao層也是一樣 該怎麼寫就怎麼寫 該怎麼註解就怎麼註解

然後可以寫一個測試類試一下連接

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. @RunWith(SpringJUnit4ClassRunner.class)  
  2. @ContextConfiguration(locations = { "classpath:spring.xml" })//這裏的spring.xml加載了第一個數據源 spring-commons.xml   
  3. public class DataSourceTest extends AbstractTransactionalJUnit4SpringContextTests {  
  4.     /** 
  5.      *  
  6.      * 功能描述:xxxxx 
  7.      * 
  8.      * @throws SQLException 
  9.      * 
  10.      * @author xxx[[email protected]] 
  11.      * 
  12.      * @since 2014年3月12日 
  13.      * 
  14.      * @update:[變更日期YYYY-MM-DD][更改人姓名][變更描述] 
  15.      */  
  16.     @Test  
  17.     @Rollback(true)  
  18.     public void testGetAllEmp() throws SQLException {  
  19.         ApplicationContext ac = new FileSystemXmlApplicationContext("classpath:config/hymanager/hymanager_spring.xml");//這裏加載的是第二個數據源配置文件路徑 使用的時候用application 讀取第二個數據源的配置文件 就可以用getBean 獲取注入的service 不用ac.getBean 用@Autowired自動注入的 則使用的是第一個數據源    
  20.         PartyService partyService = (PartyService) ac.getBean("partyService");  
  21.         List<Emp> list = partyService.getAllEmp();  
  22.         for (Emp emp : list) {  
  23.             System.out.println(emp.getEmpno());  
  24.         }  
  25.     }  

這樣就可以封裝一個父類


[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public class DataSourceChange {  
  2.     //第二個數據源數據源  
  3.     public ApplicationContext otherDataSource=new FileSystemXmlApplicationContext("classpath:config/hymanager/hymanager_spring.xml");  
  4.     //默認數據源  
  5.     public ApplicationContext defaultDataSource=new FileSystemXmlApplicationContext("classpath:config/spring_commons.xml");  
  6.     /** 
  7.      *  
  8.      * 功能描述:xxxx 
  9.      * 
  10.      * @param beanName 
  11.      * @return 
  12.      * 
  13.      * @author xxx[[email protected]] 
  14.      * 
  15.      * @since 2014年3月12日 
  16.      * 
  17.      * @update:[變更日期YYYY-MM-DD][更改人姓名][變更描述] 
  18.      */  
  19.     public Object now(String beanName) {  
  20.         return defaultDataSource.getBean(beanName);  
  21.     }  
  22.     public Object after(String beanName) {  
  23.         return otherDataSource.getBean(beanName);  
  24.     }  
  25. }  

要使用多個數據源的類就可以繼承這個父類

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public class HyMangerEmpDataHandle extends DataSourceChange {  
  2.     //用父類的after方法更換配置切換第二套數據源獲取注入partyService  
  3.     private PartyService partyService=(PartyService) after("partyService");  
  4.       
  5.     //<span style="font-family: Arial, Helvetica, sans-serif;">用父類的now方法</span>更換配置切換第一套數據源獲取注入empService  
  6.     private EmpService empService=(EmpService) now("empService");  
  7.       
  8.     private static Logger log=LoggerFactory.getLogger(PartyService.class);  
  9.     /** 
  10.      *  
  11.      * 功能描述:xxxxx 
  12.      * 
  13.      * @throws SQLException 
  14.      * 
  15.      * @author xxx[[email protected]] 
  16.      * 
  17.      * @since 2014年3月12日 
  18.      * 
  19.      * @update:[變更日期YYYY-MM-DD][更改人姓名][變更描述] 
  20.      */  
  21.     public void leadingAllEmp() throws SQLException {  
  22.         List<Emp> partyList=partyService.getAllEmp();//第二個數據源注入的service  
  23.         for(Emp emp:partyList) {  
  24.             empService.addEmp(emp);//第一個數據源注入的service  
  25.         }  
  26.     }  
  27. }  


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章