1. 程式人生 > >Panda學習筆記1——配置檔案

Panda學習筆記1——配置檔案

web.xml

配置contextConfigLocation

web.xml中定義contextConfigLocation引數,Spring會使用這個引數去載入所有逗號分隔的xml檔案,如果沒有這個引數,Spring預設載入web-inf/applicationContext.xml檔案。

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        classpath*:conf/spring/applicationContext_core*.xml,
        classpath*:conf/spring/applicationContext_dict*.xml,
        classpath*:conf/spring/applicationContext_hibernate.xml,
    </
param-value
>
</context-param>

也可以使用萬用字元來進行配置:

<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>classpath*:conf/spring/applicationContext*.xml</param-value>
</context-param>
萬用字元 說明
? 匹配單個字元
* 匹配除"/"外任意字元
** 匹配任意多個目錄

舉例如下:

classpath:app-Beans.xml

說明:無萬用字元,必須完全匹配

classpath:App?-Beans.xml

說明:匹配一個字元,例如 App1-Beans.xmlApp2-Beans.xml

classpath:user/*/Base-Beans.xml

說明:匹配零個或多個字串(只針對名稱,不匹配目錄分隔符等),例如:user/a/Base-Beans.xmluser/b/Base-Beans.xml ,但是不匹配 user/Base-Beans.xml

classpath:user/**/Base-Beans.xml

說明:匹配路徑中的零個或多個目錄

,例如:user/a/ab/abc/Base-Beans.xml,同時也能匹配 user/Base-Beans.xml

classpath:**/*-Beans.xml

說明:表示在所有的類路徑中查詢和載入檔名以“-Beans.xml”結尾的配置檔案,但重複的檔名只加載其中一個,視載入順序決定。

classpath*:user/**/*-Beans.xml
classpath*:**/*-Beans.xml

說明:classpath*:”表示載入多個資原始檔,即使重名也會被載入,比如app1.jar中有一個config-Beans.xmlapp2.jar中也有一個config-Beans.xml,這個時候,兩個都會載入。classpath*:可以用來從多個jar檔案中載入相同的檔案,且可以用來載入其它(非當前)ClassLoader的路徑裡檔案。

注意Spring路徑分割符為“/,而不能用“\\” 。

applicationContext.xml

引入引數配置檔案

Spring 3為我們提供了一種方案可以方便我們在一個階段內不需要頻繁寫一個引數的值,而在不同階段間又可以方便的切換引數的配置資訊,就是 <content:property-placeholder>元素 。

只需要在Spring配置檔案中新增一句:

<context:property-placeholder location="classpath:jdbc.properties"/>

這裡的location值為引數配置檔案的位置,配置檔案通常放到src目錄下。

引數配置檔案

引數配置檔案的格式即鍵值對的形式:

#jdbc配置
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test
username=root
password=root

行內“#”號後面部分為註釋。

配置資料來源

這樣一來就可以為Spring配置的bean的屬性設定值了,比如Spring有一個數據源的類:

<bean id="dataSource" class="org.springframework,jdbc,datasource.DriverManagerDataSource">
    <property name="driverClassName" value="${driverClassName}"/>
    <property name="url" value="${url}"/>
    <property name="username" value="${username}"/>
    <property name="password" value="${password}"/>
</bean>

配置事務管理器

<bean id="transactionManager" 
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!-- 配置DataSourceTransactionManager時需要依注入DataSource的引用 -->
        <property name="dataSource" ref="dataSource"/>
</bean>

事務代理機制

使用 Annotation 方式:

<tx:annotation-driven transaction-manager="transactionManager"/>

可以在類級別方法上使用 @Transaction 注入;

加註 @Transaction 的類或方法,本身並沒有事務行為,能被識別為事務的,其實是 tx:annotation-driven 的配置開啟了事務。

建立SqlSession

SqlSessionFactoryBean有一個必須屬性dataSource,另外其還有一個通用屬性configLocation(用來指定mybatisxml配置檔案路徑)。

<!-- 建立SqlSessionFactory,同時指定資料來源-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
	<property name="dataSource" ref="dataSource" /> 
	<!-- 指定sqlMapConfig總配置檔案,定製的environment在spring容器中不在生效-->
	<property  name="configLocation"  value="classpath:sqlMapConfig.xml"/>
</bean>

注入SqlSessionTemplate

SqlSessionTemplateMyBatis-Spring 的核心。 這個類負責管理 MyBatisSqlSession, 呼叫 MyBatisSQL 方法, 翻譯異常。

<!-- 在會話工廠中取出SqlSessionTemplate這個物件 -->
<bean id="sqlsessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
	<constructor-arg index="0" ref="sqlSessionFactory" />
</bean>

將資料對映介面轉為Spring Bean

<bean id="userDao" class="org.mybatis.spring.mapper.MapperFactoryBean">
  <property name="basePackage" value="dao"/>
  <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>

MapperScannerConfigurer將掃描basePackage所指定的包下的所有介面類(包括子類),如果它們在SQL對映檔案中定義過,則將它們動態定義為一個Spring Bean,這樣,我們在Service中就可以直接注入對映介面的bean

自動掃描

配置完這個標籤後,Spring就會去自動掃描base-package對應的路徑或者該路徑的子包下面的java檔案,如果掃描到檔案中帶有@Service,@Component,@Repository,@Controller等這些註解的類,則把這些類註冊為bean

<context:component-scan base-package="**.*.service"/>
<context:component-scan base-package="**.*.components"/>

配置AOP

<aop:config>
        <!-- 表示在所有切入點加註事務管理 -->
        <aop:pointcut expression="execution(* springlibs.service.*.*(..))" id="puintCutid" /> <!-- 需要配置 component-scan -->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="puintCutid" />
</aop:config>
  • pointcut 表示的是一些連線點的集合,使用 expression 來表達這種集合。
  • advisor 這裡就當做連線 pointcut切入點 與 advice通知 的作用。

expression表示式 : execution(* springlibs.service.*.*(..))

  • 第一個 * : 表示所有的返回值型別
  • 第二個 * : 表示所有的類
  • 第三個 * : 表示所有的方法

切入點表示式例子:

  • execution(* springlibs.service.*.*(..)) 表示 springlibs.service 下所有的類跟所有的方法
  • execution(* springlibs.service.*.save*(..)) 表示 springlibs.service 下所有的以 save 開頭的方法
  • execution(public * springlibs.service.*.*(..)) 表示 springlibs.service 下所有的公共方法

執行緒池ThreadPoolTaskExecutor配置

<!-- spring thread pool executor -->           
<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
	<!-- 執行緒池維護執行緒的最少數量 -->
	<property name="corePoolSize" value="5" />
	<!-- 允許的空閒時間 -->
	<property name="keepAliveSeconds" value="200" />
	<!-- 執行緒池維護執行緒的最大數量 -->
	<property name="maxPoolSize" value="10" />
	<!-- 快取佇列 -->
	<property name="queueCapacity" value="20" />
	<!-- 對拒絕task的處理策略 -->
	<property name="rejectedExecutionHandler">
		<bean class="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy" />
	</property>
</bean>

execute(Runable)方法執行過程:

  • 如果此時執行緒池中的數量小於corePoolSize,即使執行緒池中的執行緒都處於空閒狀態,也要建立新的執行緒來處理被新增的任務。
  • 如果此時執行緒池中的數量等於 corePoolSize,但是緩衝佇列 workQueue未滿,那麼任務被放入緩衝佇列。
  • 如果此時執行緒池中的數量大於corePoolSize,緩衝佇列workQueue滿,並且執行緒池中的數量小於maxPoolSize,建新的執行緒來處理被新增的任務。
  • 如果此時執行緒池中的數量大於corePoolSize,緩衝佇列workQueue滿,並且執行緒池中的數量等於maxPoolSize,那麼通過handler所指定的策略來處理此任務。也就是:處理任務的優先順序為:核心執行緒corePoolSize、任務佇列workQueue、最大執行緒 maximumPoolSize,如果三者都滿了,使用handler處理被拒絕的任務。
  • 當執行緒池中的執行緒數量大於corePoolSize時,如果某執行緒空閒時間超過keepAliveTime,執行緒將被終止。這樣,執行緒池可以動態的調整池中的執行緒數。

通過配置織入@Aspectj切面

通過aop名稱空間的<aop:aspectj-autoproxy />宣告自動為Spring容器中那些配置@aspectJ切面的bean建立代理。

<aop:aspectj-autoproxy />有一個proxy-target-class屬性,預設為false,表示使用jdk動態代理織入增強,當配為<aop:aspectj-autoproxy poxy-target-class="true"/>時,表示使用CGLib動態代理技術織入增強。不過即使proxy-target-class設定為false,如果目標類沒有宣告介面,則Spring將自動使用CGLib動態代理。

servlet-Context.xml

將方法返回值注入為bean

通過MethodInvokingFactoryBean類,可注入方法返回值。 MethodInvokingFactoryBean用來獲得某個方法的返回值,該方法既可以是靜態方法,也可以是例項方法。該方法的返回值可以注入bean例項屬性,也可以直接定義成bean例項。

<!--呼叫靜態方法的返回值作為bean-->
<bean id="sysProps" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
	<property name="targetClass" value="java.lang.System"/>
	<property name="targetMethod" value="getProperties"/>
</bean>

<!--呼叫例項方法的返回值作為bean-->
<bean id="javaVersion" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <property name="targetObject" ref="sysProps"/>
    <property name="targetMethod" value="getProperty"/>
    <property name="arguments" value="java.version"/>
</bean>

配置註解驅動

<mvc:annotation-driven /> 會自動註冊RequestMappingHandlerMappingRequestMappingHandlerAdapterExceptionHandlerExceptionResolver 三個bean。

還將提供以下支援:

  • 支援使用 ConversionService 例項對錶單引數進行型別轉換
  • 支援使用 @NumberFormat@DateTimeFormat
  • 註解完成資料型別的格式化
  • 支援使用 @Valid 註解對 JavaBean 例項進行 JSR 303 驗證
  • 支援使用 @RequestBody@ResponseBody 註解
<mvc:annotation-driven  message-codes-resolver ="bean ref" validator="" conversion-service="">

    <mvc:return-value-handlers>
        <bean></bean>
    </mvc:return-value-handlers>
    
    <mvc:argument-resolvers>
    </mvc:argument-resolvers>
    
    <mvc:message-converters>
    </mvc:message-converters>[/color]
    
</mvc:annotation-driven>
  • 當使用<mvc:view-controller>標籤時一定要加入<mvc:annotation-driven /> ,不然會使requestMapping失效。
  • 當為了處理靜態資源問題而加入<mvc:default-servlet-handler>時,也一定要加入<mvc:annotation-driven /> ,不然requestMapping同樣會失效。
  • 當使用自定義型別轉換器的時候需要加上<mvc:annotation-driven />標籤。

靜態資源訪問

在進行Spring MVC的配置時,通常我們會配置一個dispatcher servlet用於處理對應的URL。配置如下:

<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:spring-mvc.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>

只攔截.do請求配置如下:

<servlet-mapping>  
    <servlet-name>springMVC</servlet-name>  
    <url-pattern>*.do</url-pattern>  
</servlet-mapping> 

這表示名字為 Spring MVCservlet會處理一切的url對應的請求,那麼我們怎麼讓servlet來處理專案中的靜態資源呢?

採用Spring自帶<mvc:resources>方法。

<mvc:annotation-driven />
<mvc:resources location="/img/" mapping="/img/**"/>   
<mvc:resources location="/js/" mapping="/js/**"/>    
<mvc:resources location="/css/" mapping="/css/**"/>
  • location元素表示webapp目錄下的img包下的所有檔案
  • mapping元素表示以/img開頭的所有請求路徑,如/img/a 或者/img/a/b

該配置的作用是:DispatcherServlet不會攔截以/img開頭的所有請求路徑,並當作靜態資源交由Servlet處理。

將訪問url和檢視進行對映

Spring MVC中使用<mvc:view-controller>標籤直接將訪問url和檢視進行對映,而無需要通過控制器。

<!-- 如果當前路徑是/testMvcViewController,則交給相應的檢視解析器直接解析為檢視 -->
<mvc:view-controller path="/testMvcViewController" view-name="success" />
<!-- 重定向,如果當前路徑是/,則重定向到/index -->
<mvc:view-controller path="/" view-name="redirect:/index" />

如果沒有<mvc:annotation-driven/>,那麼所有的@Controller註解可能就沒有解析,所以當有請求時候都沒有匹配的處理請求類,就都去<mvc:default-servlet-handler/>default servlet處理了,就會導致訪問其他的頁面失敗。

整合freemarker

 <!-- freemarker的配置 -->
<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
	<property name="templateLoaderPath" value="/WEB-INF/ftl/" />
	<property name="defaultEncoding" value="utf-8" />
	<property name="freemarkerSettings">
		<props>
			<prop key="template_update_delay">10</prop>
			<prop key="locale">zh_CN</prop>
			<prop key="datetime_format">yyyy-MM-dd</prop><!-- 時間格式化 -->
			<prop key="date_format">yyyy-MM-dd</prop>
			<prop key="number_format">#.##</prop>
		</props>
	</property>
</bean>

<!-- 配置freeMarker檢視解析器 -->
<bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
	<property name="cache" value="true" />
	<property name="prefix" value="" /><!-- 上面已經配了,這裡就不用配啦 -->
	<property name="suffix" value=".ftl" />
	<property name="contentType" value="text/html;charset=UTF-8" />
	<property name="viewClass" value="org.springframework.web.servlet.view.freemarker.FreeMarkerView" />
	<property name="allowSessionOverride" value="true" />
	<property name="allowRequestOverride" value="true" />
	<property name="exposeSpringMacroHelpers" value="false" />
	<property name="exposeRequestAttributes" value="true" />
	<property name="exposeSessionAttributes" value="true" />
	<property name="requestContextAttribute" value="request" />
</bean>

配置攔截器

<mvc:interceptors>
	<!-- 日誌攔截器 -->
	<mvc:interceptor>
		<mvc:mapping path="/**" />
		<mvc:exclude-mapping path="/static/**" />
		<bean class="攔截器java程式碼路徑" />
	</mvc:interceptor>
</mvc:interceptors>
  • mvc:mapping :攔截器路徑配置
  • mvc:exclude-mapping :攔截器不需要攔截的路徑

通過配置織入@Aspectj切面

通過aop名稱空間的<aop:aspectj-autoproxy />宣告自動為Spring容器中那些配置@aspectJ切面的bean建立代理。

<aop:aspectj-autoproxy />有一個proxy-target-class屬性,預設為false,表示使用jdk動態代理織入增強,當配為<aop:aspectj-autoproxy poxy-target-class="true"/>時,表示使用CGLib動態代理技術織入增強。不過即使proxy-target-class設定為false,如果目標類沒有宣告介面,則Spring將自動使用CGLib動態代理。

引入其他配置檔案

<import resource="classpath*:/spring/job-timer.xml" />