SpringMVC集成流程
技术选型
- Spring
- Spring MVC
- MyBatis
- FreeMarker
集成的作用
- 在框架上基础上开发,发挥各个框架在各层的好处,提高开发效率
集成的本质
- Spring 去集成 Spring MVC 和 MyBatis,即控制器对象、业务对象、Mapper 对象等都交由 Spring 容器管理
- 使用 Spring IoC 和 DI 来完成对象创建及其属性注入
- 使用 AOP 来配置事务
- 使用 Spring MVC 解决 MVC 的问题,处理请求和响应
集成步骤
-
先使用Spring集成MyBatis
- 搭建项目,添加依赖配置插件。
- 把 Spring 和 MyBatis 的等配置文件拷贝进项目 resources 目录下
- 配置数据库链接池
- 配置 SqlSessionFactory
- 配置 Mapper 对象
- 配置业务对象
- 配置事务相关
-
再加入Spring MVC
- 在 web.xml 配置端控制器和编码过滤器
- 在项目 resources 目录下添加 Spring MVC 的配置文件,并配置 MVC 注解解析器,扫描控制 器,静态资源处理,视图解析器等等
- 在 Spring MVC 的配置文件中引入 Spring 配置文件
具体流程
添加依赖
<packaging>war</packaging>
<!--配置编译版本和运行版本一致依赖-->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<!--配置MySQL数据库驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.45</version>
<scope>runtime</scope>
</dependency>
<!--配置Druid连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.9</version>
</dependency>
<!--配置Spring集成MyBatis依赖 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
</dependency>
<!--配置MyBatis相关-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<!--配置Spring的IoC相关-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
<!--配置Spring测试相关 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.0.8.RELEASE</version>
<scope>test</scope>
</dependency>
<!--配置Spring JDBC相关 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
<!--配置springMVC相关-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
<!--配置Junit单元测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!--配置lombok插件 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.22</version>
<scope>provided</scope>
</dependency>
<!--配置日志-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.25</version>
</dependency>
<!--配置servlet相关-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<!--配置freemarker依赖-->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.30</version>
</dependency>
<!-- 将freemarker等第三方库整合进Spring应用上下文-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
<!--配置pagehelper分页插件-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.2.0</version>
</dependency>
<!--aspectj 配置Spring的AOP 切面相关依赖-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.13</version>
</dependency>
</dependencies>
<build>
<plugins>
<!--配置Tomcat服务器插件-->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.1</version>
<configuration>
<port>80</port> <!-- 端口 -->
<path>/</path> <!-- 上下路径 -->
<uriEncoding>UTF-8</uriEncoding> <!-- 针对 GET 方式乱码处理 -->
</configuration>
</plugin>
<!--MyBatis逆向工程插件 -->
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.2</version>
<configuration>
<verbose>true</verbose>
<overwrite>false</overwrite>
</configuration>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.45</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
MyBatis逆向工程文件内容
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<!-- 配置生成器 文件命名generatorConfig.xml-->
<generatorConfiguration>
<context id="mysql" defaultModelType="hierarchical"
targetRuntime="MyBatis3Simple">
<!--
自动识别数据库关键字,默认 false,如果设置为 true,根据 SqlReservedWords 中
定义的关键字列表;
一般保留默认值,遇到数据库关键字(Java 关键字),使用 columnOverride 覆盖
-->
<property name="autoDelimitKeywords" value="false" />
<!-- 生成的 Java 文件的编码 -->
<property name="javaFileEncoding" value="UTF-8" />
<!-- 格式化 Java 代码 -->
<property name="javaFormatter"
value="org.mybatis.generator.api.dom.DefaultJavaFormatter" />
<!-- 格式化 XML 代码 -->
<property name="xmlFormatter"
value="org.mybatis.generator.api.dom.DefaultXmlFormatter" />
<!-- beginningDelimiter 和 endingDelimiter:指明数据库的用于标记数据库对象名的
符号,比如 ORACLE 就是双引号,MYSQL 默认是`反引号 -->
<property name="beginningDelimiter" value="`" />
<property name="endingDelimiter" value="`" />
<commentGenerator>
<property name="suppressDate" value="true" />
<property name="suppressAllComments" value="true" />
</commentGenerator>
<!-- 必须要有的,使用这个配置链接数据库 @TODO:是否可以扩展 -->
<jdbcConnection
driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql:///数据库名称"
userId="数据库登录用户名"
password="数据库登录密码">
</jdbcConnection>
<!--
Java 类型处理器,用于处理 DB 中的类型到 Java中的类型,默认使用
JavaTypeResolverDefaultImpl;
注意一点,默认会先尝试使用 Integer,Long,Short 等来对应 DECIMAL 和 NUMERIC
数据类型
-->
<javaTypeResolver
type="org.mybatis.generator.internal.types.JavaTypeResolverDefaultImpl">
<!--
true:使用 BigDecimal 对应 DECIMAL 和 NUMERIC 数据类型
false:默认,
scale > 0; length > 18:使用 BigDecimal;
scale = 0; length [10,18]:使用 Long;
scale = 0; length [5,9]:使用 Integer;
scale = 0; length < 5:使用 Short
-->
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>
<!--
Java 模型创建器,是必须要的元素,负责:1,key 类(见 context 的
defaultModelType);2,Java 类;3,查询类
targetPackage:生成的类要放的包,真实的包受 enableSubPackages 属性控制;
targetProject:目标项目,指定一个存在的目录下,生成的内容会放到指定目录中,如果
目录不存在,MBG 不会自动建目录
-->
<javaModelGenerator targetPackage="实体类包路径"
targetProject="src/main/java">
<!-- for MyBatis3/MyBatis3Simple 自动为每一个生成的类创建一个构造方法,构造
方法包含了所有的 field;而不是使用 setter -->
<property name="constructorBased" value="false" />
<!-- for MyBatis3/MyBatis3Simple 是否创建一个不可变的类,如果为 true, 那
么 MBG 会创建一个没有 setter 方法的类,取而代之的是类似 constructorBased 的类 -->
<property name="immutable" value="false" />
<!-- 设置是否在 getter 方法中,对 String 类型字段调用 trim() 方法
<property name="trimStrings" value="true" /> -->
</javaModelGenerator>
<!--
生成 SQL Mapper XML 文件生成器,注意,在 MyBatis3 之后,我们可以使用
mapper.xml 文件 + Mapper接口(或者不用 mapper接口),
或者只使用 Mapper 接口 + Annotation,所以,如果 javaClientGenerator 配置
中配置了需要生成 XML 的话,
这个元素就必须配置 targetPackage/targetProject,同 javaModelGenerator
-->
<sqlMapGenerator targetPackage="Mapper接口包路径"
targetProject="src/main/resources">
<!-- 在 targetPackage 的基础上,根据数据库的 schema 再生成一层 package,最
终生成的类放在这个 package 下,默认为 false -->
<property name="enableSubPackages" value="true" />
</sqlMapGenerator>
<!--
对于 MyBatis 来说,即生成 Mapper 接口,注意,如果没有配置该元素,那么默认不会
生成 Mapper 接口,targetPackage/targetProject 同 javaModelGenerator
type:选择怎么生成 Mapper 接口(在 MyBatis3/MyBatis3Simple下):
1,ANNOTATEDMAPPER:会生成使用 Mapper 接口 + Annotation 的方式创建
(SQL 生成在 annotation 中),不会生成对应的 XML;
2,MIXEDMAPPER:使用混合配置,会生成 Mapper 接口,并适当添加合适的
Annotation,但是 XML 会生成在 XML 中;
3,XMLMAPPER:会生成 Mapper 接口,接口完全依赖 XML;
注意,如果 context 是 MyBatis3Simple:只支持 ANNOTATEDMAPPER 和
XMLMAPPER
-->
<javaClientGenerator targetPackage="Mapper接口对应xml文件路径" type="XMLMAPPER"
targetProject="src/main/java">
<!-- 在 targetPackage 的基础上,根据数据库的 schema 再生成一层 package,最
终生成的类放在这个 package 下,默认为 false -->
<property name="enableSubPackages" value="true" />
<!-- 可以为所有生成的接口添加一个父接口,但是 MBG 只负责生成,不负责检查
<property name="rootInterface" value=""/> -->
</javaClientGenerator>
<!-- 配置表,根什么表生成 -->
<table tableName="数据表名名称">
<property name="useActualColumnNames" value="false"/>
<property name="constructorBased" value="false" />
<generatedKey column="id" sqlStatement="JDBC" />
</table>
</context>
</generatorConfiguration>
Spring 集成MyBatis
-
配置数据库连接池
<!-- 关联 db.properties 文件 --> <context:property-placeholder location="classpath:db.properties"/> <!-- 配置 DataSource bean --> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" initmethod="init" destroy-method="close"> <property name="driverClassName" value="${jdbc.driverClassName}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </bean>
-
配置SqlSessionFactory Bean
<!-- 配置 SqlSessionFactory bean --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- 关联主配置文件 可以不配置--> <property name="configLocation" value="classpath:mybatis-config.xml"/> <!-- 配置别名 若不用别名,可以不配置 --> <property name="typeAliasesPackage" value="实体类包路径"/> <!-- 配置数据源--> <property name="dataSource" ref="dataSource"/> <!-- 关联 Mapper XML 可以不配置, 前提编译 Mapper 接口字节码文件与 Mapper XML 文件在 一起,文件名也一样 --> </bean>
-
配置Mapper bean
<!-- 配置 Mapper bean --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <!-- 指定 Mapper 接口所在包 --> <property name="basePackage" value="Mapper接口包路径r"/> </bean>
-
配置业务相关Service bean
<!-- 配置 IoC DI 注解解析器 , 让 Spring 帮我们创建业务接口的实现类对象, 完成属性或者字段注 入 --> <context:component-scan base-package="扫描指定包路径"/>
-
配置事务相关
<!-- 配置事务管理器 WHAT--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!-- 配置 AOP --> <aop:config>
<!--配置事务注解解析器 替代下面xml配置方式--> <tx:annotation-driven transaction-manager="transactionManager"/> <!-- 配置增强,包含 WHEN,并关联上面 WHAT--> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="get*" read-only="true"/> <tx:method name="select*" read-only="true"/> <tx:method name="query*" read-only="true"/> <tx:method name="count*" read-only="true"/> <tx:method name="list*" read-only="true"/> <tx:method name="*"/> </tx:attributes> </tx:advice>
<!-- 配置切点切面表示使用CGLIB动态代理技术织入增强 替代下面配置--> <aop:aspectj-autoproxy proxy-target-class="true" /> <!-- WHERE --> <aop:pointcut id="txPointcut" expression="execution(* cn.wolfcode.service.impl.*ServiceImpl.*(..))"/> <!-- 关联 WHERE WHEN--> <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/> </aop:config>
集成Spring MVC
-
在web.xml配置前端控制器和编码过滤器
<!-- 配置前端控制器 --> <servlet> <servlet-name>dispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servletclass> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:mvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <!-- 配置编码过滤器, 针对 POST --> <filter> <filter-name>characterEncodingFilter</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> <filter-mapping> <filter-name>characterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
-
创建mvc.xml Spring MVC 配置文件
<!-- IoC DI 注解解析器,配置扫描控制器。说人话:让 Spring 帮我们创建控制器对象,并注入 --> <context:component-scan base-package="控制器包路径"/> <!-- 配置 MVC 注解解析器,时间注解,JSON 注解 --> <mvc:annotation-driven/> <!-- 处理静态资源 --> <mvc:default-servlet-handler/> <!-- 注册 FreeMarker 配置类 --> <bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer"> <!-- 配置 FreeMarker 的文件编码 --> <property name="defaultEncoding" value="UTF-8" /> <!-- 配置 FreeMarker 寻找模板的路径 --> <property name="templateLoaderPath" value="/WEB-INF/views/" /> <property name="freemarkerSettings"> <props> <!-- 兼容模式 ,配了后不需要另外处理空值问题,时间格式除外 --> <prop key="classic_compatible">true</prop> <!-- 数字格式化 , 不会有,字符串的 --> <prop key="number_format">0.##</prop> </props> </property> </bean> <!-- 注册 FreeMarker 视图解析器 --> <bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver"> <!-- 是否把session中的attribute复制到模板的属性集中,可以使用FreeMarker的表达式来访问并显示--> <property name="exposeSessionAttributes" value="true" /> <!-- 配置逻辑视图自动添加的后缀名 --> <property name="suffix" value=".ftl" /> <!-- 配置响应头中 Content-Type 的指 --> <property name="contentType" value="text/html;charset=UTF-8" /> </bean>
-
在Spring MVC的配置文件引入Spring 配置文件
<!-- 引入 applicationContext.xml --> <import resource="classpath:applicationContext.xml"/>
使用Pagehelper分页插件的配置
在Spring配置文件applicationContext.xml中的SqlSessionFactoryBean中加入插件配置
<!--配置SqlSessionFactory对象-->
<bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="plugins">
<array>
<bean class="com.github.pagehelper.PageInterceptor">
<property name="properties">
<!--使用下面的方式配置参数,一行配置一个,下面配的是合理化分页 -->
<value>
pageSizeZero=true
reasonable=true
</value>
</property>
</bean>
</array>
</property>
</bean>
插件逻辑实现
public PageInfo<Example> query(QueryObject qo) {
PageHelper.startPage(qo.getCurrentPage(), qo.getPageSize());
List<Example> list = exampleMapper.queryList(qo);
return new PageInfo<>(list);
}
文件导出和上传相关设置
-
添加依赖
<!--poi 配置POI 导出Excel依赖--> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>4.1.2</version> </dependency> <!--fileupload 配置文件上传依赖--> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.1</version> </dependency>
-
在springmvc的配置文件中配置文件上传配置
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="maxUploadSize" value="#{1024*1024*10}"/> </bean>
其他配置
配置log4j.properties文件
# Global logging configuration
log4j.rootLogger=ERROR, stdout
log4j.logger.Mapper接口路径=TRACE
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
配置db.properties文件
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/数据库名称
jdbc.username=登录用户名
jdbc.password=登录密码
配置mybatis-caonfig.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>
</configuration>
Spring MVC执行流程
文字描述
- 用户发送出请求到前端控制器 DispatcherServlet
- DispatcherServlet 收到请求调用 HandlerMapping(处理器映射器)
- HandlerMapping 找到具体的处理器(通过 XML 或注解配置),生成处理器对象及处理器拦截器(若有),再一起返回给 DispatcherServlet
- DispatcherServlet 调用 HandlerAdapter(处理器适配器)
- HandlerAdapter 经过适配调用具体的处理器的某个方法(Handler/Controller)
- Controller 执行完成返回 ModelAndView 对象
- HandlerAdapter 将 Controller 返回的 ModelAndView 再返回给 DispatcherServlet
- DispatcherServlet 将 ModelAndView 传给 ViewReslover(视图解析器)
- ViewReslover 解析后返回具体 View(视图)
- DispatcherServlet 根据 View 进行渲染视图(即将模型数据填充至视图中
- DispatcherServlet 响应用户
总结
到此SpringMVC的集成流程基本完成,集成最重要的是处理好每个环节的相关配置,如果配置出问题,会给后续开发带来很大影响,比如一些幽灵Bug的出现等等…