springMVC配置流程
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继续处理。