这首诗表达了诗人韩愈对SpringMVC的无限热爱之情。诗人说:朝闻道,夕死可矣。于是,有了这一篇博客。
- 搭建一个SpringMVC程序。
- 解读SpringMVC的配置文件,尤其是DispatcherServlet和ContextLoaderListener。
- 比较基于XML配置和基于Java配置的DispatcherServlet和ContextLoaderListener。
遥想当年,寡人为了搭建一个SpringMVC的Hello World整整花了两天。并不是它有多难,而是IDEA配置出错,但是当时不知道。寡人在此愿发慈悲心,为Java小菜鸟将一个SpringMVC的完整过程呈现出来。如果你仍然搭建不出来,那么可见你和寡人一样,都是Spring的祭品。
- 搭建一个SpringMVC程序。
第一步:准备工具IDEA,Maven。
第二步:搭建环境使用maven搭建,首先将web项目的骨架搭建出来,中间脑残细节,省略。
pom.xml文件完整如下:
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.7</maven.compiler.source> <maven.compiler.target>1.7</maven.compiler.target> <springmvc-version>5.0.0.RELEASE</springmvc-version> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${springmvc-version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${springmvc-version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>${springmvc-version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${springmvc-version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${springmvc-version}</version> </dependency> </dependencies>
仔细看目录结构,此时还不是SpringMVC项目,需要添加SpringMVC框架支持。
添加了框架支持以后的项目结构,明显多了两个xml文件。
这是没有添加SpringMVC框架支持以前的web.xml
这是添加了SpringMVC框架支持以后的web.xml
配置tomcat, 启动服务器
发送hello.mvc请求
- 解读SpringMVC的配置文件,尤其是DispatcherServlet和ContextLoaderListener。
ContextLoaderListener来到这个世界上是为了什么?DispatcherServlet的目的又是什么?一切存在皆合理。
注意ContextLoaderListener是什么?本质上是一个Listener,DispatcherServlet本质上又是什么?是一个Servlet。
说到这里,如果你足够聪明,那么ContextLoaderListener和DispatcherServlet的第一点区别就已经是犹抱琵琶半遮面啦。
可是,如果你并没有我想象地那么机动,那么请往下看,我修改web.xml中的ContextLoaderListener和DispatcherServlet的相对位置。
修改前:
<web-app> <display-name>Archetype Created Web Application</display-name> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/applicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>*.form</url-pattern> </servlet-mapping> </web-app>
修改后:
看到没,变更servlet和listener的顺序就会出现错误。错误提示如下:
什么意思?意思就是说web-app中tag的顺序必须要按照指定的顺序摆放。因为程序的加载是按照顺序加载的,这说明什么?这说明listener必须先要加载,然后servlet才可以加载。所以在加载顺序上,ContextLoaderListener先于DispatcherServlet。一个事物的产生必须要在另一个事物之后,这说明什么?其实,ContextLoaderListener上下文的作用范围是Spring全局,但是DispatcherServlet上下文仅仅是web层。这是整体和局部的关系。DispatcherServlet负责加载web层的bean,ContextLoaderListener负责加载业务层和持久层的bean。何以见得?
<servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>*.form</url-pattern> </servlet-mapping>
DispatcherServlet加载的应用上下文是dispatcher-servlet.xml
<context:component-scan base-package="com.logic.controller"></context:component-scan> <context:annotation-config/> <mvc:annotation-driven/> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/view/"></property> <property name="suffix" value=".jsp"></property> </bean>
<context:component-scan base-package="com.logic.controller"></context:component-scan>扫描包中带有@Component注解的组件bean,比如@Controller, @Service, @Repository。
<context:annotation-config/>将@Component组件注入容器。
<mvc:annotation-driven/>处理@Controller映射匹配。
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/view/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
InternalResourceViewResolver视图资源解析。
这些都是web端MVC的范畴,那ContextLoaderListener呢?如果你接触过SSH框架,那你一定见到过 在applicationContext.xml中配置数据库。不错,ContextLoaderListener负责加载后端数据层组件,比如dataSource啊,bean和table之间的对应关系啊。
--------------------------------------------------------睡觉 未完待续------------------------------------------------------------