spring学习

springMVC配置流程

2017-07-30  本文已影响49人  不知名的蛋挞

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加载流程

  1. 启动一个WEB项目的时候,容器(如:Tomcat)会去读它的配置文件web.xml,读两个节点: <listener></listener> 和 <context-param></context-param>。其中<context-param>用来声明应用范围(整个WEB项目)内的上下文初始化参数。
  2. 紧接着,容器创建一个ServletContext(上下文),这个WEB项目所有部分都将共享这个上下文。
  3. 容器将<context-param></context-param>转化为键值对,并交给ServletContext。
  4. 容器创建<listener></listener>中的类实例,即创建监听。
  5. 在监听中会有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种方法。

  1. 配置一个处理静态资源的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就是处理静态资源请求的类,当然如果你愿意,也可以自己尝试写一个。

  1. 采用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 />完全打破了这个限制。

  1. 采用<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继续处理。

上一篇下一篇

猜你喜欢

热点阅读