1.配置web.xml
web.xml這個是tomcat默認自動讀取的xml,是tomat官方規定的,一般用于配置servlet,是整個web程序的一個配置入口。最早的時候,這個web.xml的作用適用于注冊servlet、filter、listener等,tomcat讀取web.xml中的信息后,才能將url與對應的servlet綁定起來。
??創建好web.xml后如圖,如下圖是2.3的老版本:
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
</web-app>
如果想換到更高級的版本,可以在Windows的環境下,直接打開tomcat下的webapps/examples/WEB-INF目錄下的web.xml修改即可。打開該文件之后復制servlet3.1的xml頭放到項目的web.xml中:
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmls:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web- app_3_1.xsd"
version="3.1"
metadata-complete="true">
<display-name>Archetype Created Web Application</display-name>
</web-app>
我們在使用SpringMVC的時候,就需要在web.xml配置一個入口,這個入口接收各種請求,然后再由SpringMVC框架去進行分發。
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath*:/applicationContext.xml
</param-value>
</context-param>
<filter>
<filter-name>Encoding</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>
</filter>
<!-- 創建spring的監聽器,用以啟動容器,并加載Spring配置 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--配置前端控制器-->
<!--Dispatcher作為統一的訪問點,進行全局的流程控制。-->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:applicationContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
【說明】
(1)web.xml加載流程
- 啟動一個WEB項目的時候,容器(如:Tomcat)會去讀它的配置文件web.xml,讀兩個節點: <listener></listener> 和 <context-param></context-param>。其中<context-param>用來聲明應用范圍(整個WEB項目)內的上下文初始化參數。
- 緊接著,容器創建一個ServletContext(上下文),這個WEB項目所有部分都將共享這個上下文。
- 容器將<context-param></context-param>轉化為鍵值對,并交給ServletContext。
- 容器創建<listener></listener>中的類實例,即創建監聽。
- 在監聽中會有contextInitialized(ServletContextEvent args)初始化方法,在這個方法中獲得ServletContext = ServletContextEvent.getServletContext();
(2)在<context-param>部署bean.xml。
??contextConfigLocation定義了要裝入Spring的配置文件(bean.xml)。在上面的代碼中,applicationContext.xml即為bean.xml(下面會進行配置)。下面介紹配置它的存放路徑的方法。
??Spring可以通過指定classpath*:與classpath:前綴加路徑的方式從classpath加載文件。
Java中的classpath
??src不是classpath, WEB-INF/classes,lib才是classpath,WEB-INF/ 是資源目錄, 客戶端不能直接訪問。WEB-INF/classes目錄存放src目錄Java文件編譯之后的class文件,xml、properties等資源配置文件,這是一個定位資源的入口。引用classpath路徑下的文件,只需在文件名前加classpath:。
classpath:只能加載找到的第一個classpath文件。
classpath:當項目中有多個classpath路徑,并同時加載多個classpath路徑下(此種情況多數不會遇到)的文件,就發揮了作用,如果不加,則表示僅僅加載第一個classpath路徑。所以使用classpath也就可以從多個jar文件中加載相同的文件。即是以classpath*開頭,它會遍歷classpath。
??比如 resource1.jar和resource2.jar中的package 'com.test.rs' 都有一個 'jarAppcontext.xml' 文件,通過使用下面的代碼則可以將兩個jar包中的文件都加載進來:
classpath*:com/test/rs/jarAppcontext.xml
而如果寫成下面的代碼,就只能找到其中的一個xml文件(順序取決于jar包的加載順序):
classpath:com/test/rs/jarAppcontext.xml
classpath*:的加載使用了classloader的 getResources()
方法,如果是在不同的J2EE服務器上運行,由于應用服務器提供自己的classloader實現,它們在處理jar文件時的行為也許會有所不同。 要測試classpath*:是否有效,可以用classloader從classpath中的jar文件里加載文件來進行測試:getClass().getClassLoader().getResources("<someFileInsideTheJar>")。
Spring的配置文件啟動時,加載的是WEB-INF下面的bean.xml,運行時使用的是WEB-INF/classes目錄下的bean.xml。
??在<param-value> </param-value>里指定相應的xml文件名,如果有多個xml文件,可以寫在一起并一“,”號分隔。也可以采用通配符,如applicationContext-*.xml,,比如這那個目錄下有applicationContext-ibatis-base.xml,applicationContext-action.xml,applicationContext-ibatis-dao.xml等文件,都會一同被載入。
2.配置bean.xml(application.xml)
bean.xml主要是用來配置springm的事務的,通常命名為application.xml。一個項目中可以有好幾個application.xml,用以配置不同的事務。這里我們使用springmvc+hibernate的配置為示例。
applicationContext.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"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd ">
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:jdbc.properties</value>
<value>classpath:redis.properties</value>
</list>
</property>
</bean>
<!--引入其他bean.xml的配置-->
<import resource="applicationContext-aop.xml" />
<import resource="applicationContext-mvc.xml" />
<import resource="applicationContext-mybatis.xml" />
<import resource="applicationContext-transaction.xml" />
<import resource="applicationContext-task.xml" />
<import resource="applicationContext-redis.xml" />
</beans>
【說明】
(1)PropertyPlaceholderConfigurer是spring提供我們來把一些環境變量(數據庫連接相關參數,文件路徑等)統一管理起來,然后在bean中指定對應的變量的。實際上,PropertyPlaceholderConfigurer起的作用就是將占位符指向的數據庫配置信息放在bean中定義。
applicationContext-aop.xml(配置AOP)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">
<!--開啟注解式AOP-->
<aop:aspectj-autoproxy />
</beans>
applicationContext-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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<!-- 初始化連接大小 -->
<property name="initialSize" value="${jdbc.initialSize}"></property>
<!-- 連接池最大數量 -->
<property name="maxActive" value="${jdbc.maxActive}"></property>
</bean>
<!-- 基于sqlSessionTemplate的mybatis配置 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mapperLocations" value="classpath*:mapper/*.xml" />
</bean>
<!-- sqlSessionTemplate配置 -->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory" />
</bean>
</beans>
applicationContext-transaction.xml(配置事務)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.2.xsd ">
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!--開啟注解式事務-->
<tx:annotation-driven transaction-manager="transactionManager" />
</beans>
applicationContext-mvc.xml(配置SpringMVC)
<?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: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/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<!--通過annotation來配置控制器 -->
<mvc:annotation-driven/>
<!--配置靜態資源的訪問-->
<mvc:resources mapping="/css/**" location="/css/" />
<mvc:resources mapping="/images/**" location="/images/" />
<mvc:resources mapping="/js/**" location="/js/" />
<!-- 掃描有注解的文件 base-package 包路徑 -->
<context:component-scan base-package="com.zyt.controller" />
<context:component-scan base-package="com.zyt.dao" />
<context:component-scan base-package="com.zyt.service" />
</beans>
【說明】
(1)<mvc:annotation-driven />、<context:annotation-config />和<context:component-scan>的區別
<context:annotation-config> declares support for general annotations such as @Required, @Autowired, @PostConstruct, and so on.<context:annotation-config>主要是解決spring容器的一些注解。
<mvc:annotation-driven /> is actually rather pointless. It declares explicit support for annotation-driven MVC controllers (i.e.@RequestMapping, @Controller, etc), even though support for those is the default behaviour.<mvc:annotation-driven />是spring MVC為@Controllers分發請求所必須的,并提供了數據綁定支持。
<context:component-scan>做了<context:annotation-config>要做的事情,還額外支持@Component,@Repository,@Service,@Controller注解。并且<context:component-scan>掃描base-package并且在application context中注冊掃描的beans。所以配置<context:component-scan>就不需要配置<context:annotation-config/>
(2)<mvc:resources>標簽的作用
??我們知道Dispatcher的servlet會使用 / 攔截了所有的請求,而對靜態資源的訪問也屬于一個請求,然后進入它的匹配流程,根據HandlerMapping的配置來匹配的。但是對于靜態資源來說,默認的Spring MVC是沒有注冊匹配規則的,此時若你去請求一個靜態資源,則會報404錯誤,比如頁面上引用的css,js等效果不起作用了。怎么辦呢?這里有3種方法。
- 配置一個處理靜態資源的HandlerMapping
<bean id="resourceHttpRequestHandler" class="org.springframework.web.servlet.resource.ResourceHttpRequestHandler">
<property name="locations" value="classpath:/META-INF/resources/"></property>
</bean>
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/resources/**">ResourceHttpRequestHandler</prop>
</props>
</property>
</bean>
其中ResourceHttpRequestHandler就是處理靜態資源請求的類,當然如果你愿意,也可以自己嘗試寫一個。
- 采用spring自帶<mvc:resources>方法。
//location是工程路徑地址,mapping是映射后的訪問地址
<mvc:resources mapping="/images/**" location="/static_resources/images/"/>
<mvc:resources />由Spring MVC框架自己處理靜態資源,并添加一些有用的附加值功能。本質上也是把ResourceHttpRequestHandler注冊到SimpleUrlHandlerMapping上。
??<mvc:resources />允許靜態資源放在任何地方,如WEB-INF目錄下、類路徑下等,你甚至可以將JavaScript等靜態文件打到JAR包中。通過location屬性指定靜態資源的位置,由于location屬性是Resources類型,因此可以使用諸如"classpath:"等的資源前綴指定資源位置。傳統Web容器的靜態資源只能放在Web容器的根路徑下,<mvc:resources />完全打破了這個限制。
- 采用<mvc:default-servlet-handler/> 方法。
<mvc:default-servlet-handler/>
<mvc:default-servlet-handler/> 只能在SpringMVC3.0之后使用,且對于匹配規則為"/"的DispatcherServlet才生效(因為別的匹配規則一般也不會攔截靜態資源)。配置<mvc:default-servlet-handler />后,會在Spring MVC上下文中定義一個org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler。它會像一個檢查員,對進入DispatcherServlet的URL進行篩查,如果發現是靜態資源的請求,就將該請求轉由Web應用服務器默認的Servlet處理,如果不是靜態資源的請求,才由DispatcherServlet繼續處理。