SpringMVC学习相关总结
前言:近期从学习s2sh框架转到SpringMVC,写下此随笔记录学习中的问题和总结,方便日后进行查阅
SpringMVC框架特点
相比较Struts2来说,SpringMVC是一个轻量级的MVC框架。之所以说轻量级,是因为Struts2是基于类级别的拦截,针对每一个请求,都需要一个对应的Action来进行处理,而SpringMVC是基于方法级别的拦截,开发效率和执行效率要高于Struts2.
SpringMVC的核心是一个DispatcherServlet类。与大多数javaWeb框架一样,SpringMVC所有的请求都会通过一个前端控制器Servlet,也就是DispatcherServlet
DispatcherServlet的任务就是将请求发送给SpringMVC控制器,即一个Controller。控制器是一个用于处理请求的Spring组件。
通过以上内容,对SpringMVC有了一个大概的了解,接下里将进行一个简单的SpringMVC框架的配置。
配置SpringMVC
补充:Servlet3.0新特性:
- 异步处理支持:有了该特性,Servlet 线程不再需要一直阻塞,直到业务处理完毕才能再输出响应,最后才结束该 Servlet 线程。在接收到请求之后,Servlet 线程可以将耗时的操作委派给另一个线程来完成,自己在不生成响应的情况下返回至容器。针对业务处理较耗时的情况,这将大大减少服务器资源的占用,并且提高并发处理速度。
- 新增的注解支持:该版本新增了若干注解,用于简化 Servlet、过滤器(Filter)和监听器(Listener)的声明,这使得 web.xml 部署描述文件从该版本开始不再是必选的了。
- 可插性支持:熟悉 Struts2 的开发者一定会对其通过插件的方式与包括 Spring 在内的各种常用框架的整合特性记忆犹新。将相应的插件封装成 JAR 包并放在类路径下,Struts2 运行时便能自动加载这些插件。现在 Servlet 3.0 提供了类似的特性,开发者可以通过插件的方式很方便的扩充已有 Web 应用的功能,而不需要修改原有的应用。
传统的Servlet配置方式是采用web.xml文件进行配置。但是在Servlet3的新规范中,并不推荐这种配置方式,而通过spring3.1之后的功能增强和Servlet3的新规范,可以使用一种更便捷的新方法,通过java类的方式来配置DispatcherServlet
首先,需要新建一个类,继承AbstractAnnotationConfigDispatcherServletInitializer类,我将这个类命名为MyWebAppInitializer
MyWebAppInitializer.java
package com.song.web.config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
import javax.servlet.Filter;
import javax.servlet.MultipartConfigElement;
import javax.servlet.ServletRegistration;
public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] {RootConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] {WebConfig.class};
}
@Override
protected String[] getServletMappings() {
return new String[] {"/"};
}
/**
* 可用此方法配置Filter
* @return
*/
@Override
protected Filter[] getServletFilters() {
return new Filter[] {};
}
/**
* 上传文件参数配置
* @param registration
*/
@Override
protected void customizeRegistration(ServletRegistration.Dynamic registration) {
registration.setMultipartConfig(
new MultipartConfigElement("d:/tmp/",419430400,419430400,0)
);
}
}
下面对这个类进行说明,为什么要创建一个这样的类?在Servlet3.0的环境中,容器会在类路径中查找实现了javax.servlet.ServletContainerInitializer接口的类,如果找到了这个类,就用它来配置Servlet容器。幸运的是,Spring已经提供了这个接口的实现,那就是SpringServletContainerInitializer这个类,这个类又会反过来查找实现了WebApplicationInitializer接口的类,并将非陪的任务交给他们完成。Spring3.2之后提供了一个便利的实现,那就是AbstractAnnotationConfigDispatcherServletInitializer这个类,由于MyWebAppInitializer继承了这个类,也就同时实现了WebApplicationInitializer这个接口,所以当部署到Servlet3.0容器中的时候,容器就会自动发现它,并用来配置Servlet上下文。通过其中的方法,即可完成对DispatcherServlet的配置
下面对类中的方法进行说明
getRootConfigClasses():返回一个Spring配置类数组,用来配置其他工具bean类,例如DataSource,Mybatis,Service类等等。
getServletConfigClasses():返回一个springMVC配置类数组,用来配置与web相关的bean类,例如controller类等等。
AbstractAnnotationConfigDispatcherServletInitializer在初始化的时候,会自动帮我们注册DispatcherServlet类,并根据getServletConfigClasses()提供的配置类创建servletContext,但在SpringWeb应用中,一般还会有另一个ApplicationContext,是由ContextLoaderListener创建的,其中ApplicationContext是ServletContext的父容器,也就是说ServletContext可以访问ApplicationContext中声明的bean。
除了以上简单配置外,另外springMVC所需要的各种过滤器并没有在其中进行配置,感觉这样配置的话会显得很杂乱,所以我个人是将这些过滤器在wwb.xml中进行配置,如编码过滤器配置如下:
<filter>
<filter-name>encodingFilter</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>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/</url-pattern>
</filter-mapping>
其中RootConfig.java代码如下:
package com.song.web.config;
import org.springframework.context.annotation.*;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
/**
* 声明为配置类,用于配置Spring容器
*/
@Configuration
/**
* 导入其他配置文件,当只能通过mxl配置某些组件的时候可以考虑这种方式,此处用于引入Spring组件的相关配置
*/
@ImportResource("classpath:xml/spring-mybatis.xml")
/**
* 配置组件扫描,自动扫描相关包下使用@Component、@Controller、@Service等注解的类,将其配置为bean组件
*/
@ComponentScan(basePackages ={"com.song"},
excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,value = EnableWebMvc.class)})
public class RootConfig {
}
WebConfig.java
package com.song.web.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.support.StandardServletMultipartResolver;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
@Configuration
/***
* 启用SpringMvc的支持
*/
@EnableWebMvc
@ComponentScan("com.song,web")
public class WebConfig extends WebMvcConfigurerAdapter{
/**
* 注册一个简单的视图解析器
* @return
*/
@Bean
public ViewResolver viewResolver(){
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
resolver.setExposeContextBeansAsAttributes(true);
return resolver;
}
/**
* 用于上传操作的组件
* @return
*/
@Bean
public MultipartResolver multipartResolver(){
return new StandardServletMultipartResolver();
}
/**
* 配置静态资源的处理,将静态资源的请求转发到Servlet容器中默认的Servlet上
* @param configurer
*/
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
以上便完成了一个简单的SpringMVC框架配置,接下来为SpringMVC配置Mybatis持久层支持
整合Mybatis框架
加入Mybatis相关组件
首先需要数据源,本例采用数据源为dbcp2,整个配置文件如下:
spring-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">
<!-- 3.配置SqlSessionFactory对象 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 注入数据库连接池 -->
<property name="dataSource" ref="dataSource" />
<!-- 配置MyBaties全局配置文件:spring-mybatis.xml -->
<property name="configLocation" value="classpath:xml/mybatis-config.xml" />
<!-- 扫描sql配置文件:mapper需要的xml文件,当Mapper接口和xml文件在同一个目录下时,可省略此项 -->
<property name="mapperLocations" value="classpath:com/song/web/model/*.xml" />
</bean>
<!--4.配置扫描Dao接口包,动态实现Dao接口,注入到spring容器中-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 注入sqlSessionFactory -->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
<!-- 给出需要扫描Dao接口包 -->
<property name="basePackage" value="com.song.web.mapper" />
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/baron"/>
<property name="username" value="root"/>
<property name="password" value="songjin"/>
</bean>
</beans>
将xml导入到前文所提到的RootConfigjava类中即可完成配置接下来需要对Mybatis进行全局的配置
mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 配置全局属性 -->
<settings>
<!-- 使用jdbc的getGeneratedKeys获取数据库自增主键值 -->
<setting name="useGeneratedKeys" value="true" />
<!-- 使用列别名替换列名 默认:true -->
<setting name="useColumnLabel" value="true" />
<!-- 开启驼峰命名转换:Table{create_time} -> Entity{createTime} -->
<setting name="mapUnderscoreToCamelCase" value="true" />
</settings>
</configuration>
配置完成之后,就可以配置相应的Controller和Service进行测试了,这里就不一一详细说明了。