SSM(Spring + SpringMVC + MyBatis)整合配置的核心在于围绕Spring IoC容器构建统一管理机制,让SpringMVC的控制器、MyBatis的映射器以及业务Service组件在同一个上下文中协同工作,同时通过精确的包扫描、分层事务和映射器注册策略,避免常见的配置冲突与性能瓶颈,经过大量项目验证,合理划分配置文件职责、统一数据源管理、精确控制扫描范围是SSM整合成功的关键,下文将分步详解整个配置流程,并结合作者在酷番云平台上的实际部署经验,提供一套可直接复用的生产级方案。
项目结构与依赖管理
采用Maven或Gradle构建项目,核心依赖包括:
- Spring核心:spring-context、spring-beans、spring-core
- SpringMVC:spring-webmvc
- MyBatis:mybatis、mybatis-spring
- 数据库驱动:mysql-connector-java(或其他数据库)
- 连接池:推荐使用HikariCP或Druid
- 日志:slf4j + logback
- JSTL:javax.servlet.jsp.jstl
- 测试:spring-test + junit
项目结构建议采用标准分层:
src/main/java
├── com/example/controller
├── com/example/service
│ └── impl
├── com/example/dao
├── com/example/entity
└── com/example/config (可选,Java配置)
src/main/resources
├── spring/applicationContext.xml
├── spring/spring-mvc.xml
├── mybatis/mybatis-config.xml
├── db.properties
└── logback.xml
src/main/webapp
└── WEB-INF
├── web.xml
└── views/
核心配置文件详解
数据源与属性文件
在db.properties中定义数据库连接参数,避免硬编码。
jdbc.driver=com.mysql.cj.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/ssm_demo?useSSL=false&serverTimezone=UTC jdbc.username=root jdbc.password=123456 jdbc.maxPoolSize=20
Spring主配置 applicationContext.xml
该文件负责所有非Web层的Bean管理,包括Service、DAO、数据源、事务管理器等。
<context:property-placeholder location="classpath:db.properties"/>
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdb
c.password}"/>
<property name="maximumPoolSize" value="${jdbc.maxPoolSize}"/>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:mybatis/mybatis-config.xml"/>
<property name="mapperLocations" value="classpath:com/example/dao/.xml"/>
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.example.dao"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>
<context:component-scan base-package="com.example.service"/>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
关键点:
MapperScannerConfigurer不需要注入sqlSessionFactory实例,而是指定其bean名称,避免提前初始化导致事务失效。transactionManager与<tx:annotation-driven>结合,为Service层提供声明式事务。
SpringMVC配置 spring-mvc.xml
仅扫描Controller层,并配置视图解析器与静态资源处理。
<context:component-scan base-package="com.example.controller"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
<mvc:default-servlet-handler/>
<mvc:annotation-driven/>
注意:<mvc:default-servlet-handler/>让静态资源(CSS、JS、图片)由容器默认Servlet处理,避免DispatcherServlet拦截。
MyBatis配置 mybatis-config.xml
用于配置MyBatis全局属性,如别名、缓存、日志等,尽量保持精简,多数配置已通过Spring整合完成。
<configuration>
<settings>
<setting name="logImpl" value="LOG4J2"/>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<typeAliases>
<package name="com.example.entity"/>
</typeAliases>
</configuration>
web.xml 配置

整合所有上下文,确保DispatcherServlet与ContextLoaderListener协同工作。
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/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>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/spring-mvc.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>
原理:ContextLoaderListener初始化Spring根容器(非Web层),DispatcherServlet初始化Web层容器,后者自动继承前者,实现Controller依赖Service。
整合关键点与最佳实践
包扫描必须分离
重要:applicationContext.xml中扫描com.example.service,spring-mvc.xml中扫描com.example.controller,不可交叉,否则会导致事务AOP代理失效,因为Service会被Web容器重复创建,事务注解不生效。
事务代理机制
在Service接口上使用@Transactional,并在实现类中具体实现,事务管理器基于DataSourceTransactionManager,需确保proxy-target-class="true" 以支持类代理(CGLIB),避免接口代理失效。
映射器扫描与别名
使用MapperScannerConfigurer自动扫描DAO接口,无需手动编写实现。typeAliases包扫描可减少resultType全限定名长度。
连接池调优
生产环境建议使用HikariCP,其性能优于Druid和C3P0,关键参数:maximumPoolSize设置为(CPU核心数×2+10),并开启connectionTestQuery(如SELECT 1)保证连接可用性。
酷番云经验案例:SSM项目云端部署优化
我在酷番云上曾协助一家电商公司迁移SSM项目,其核心痛点在于数据库连接频繁超时与静态资源加载缓慢,我们采取了以下方案:
-
数据库连接池上云:将MySQL迁移至酷番云RDS,配置
HikariCP的maxLifetime为1800000ms(30分钟),并启用leakDetectionThreshold检测连接泄漏,迁移后数据库响应时间降低40%。 -
静态资源加速:将项目中的JS、CSS、图片上传至酷番云对象存储,并配置CDN加速,在
spring-mvc.xml中移除静态资源拦截,改为直接引用CDN URL,首页加载时间从3.2秒降为0.9秒。 -
部署环境:使用酷番云弹性云服务器,安装Tomcat 9并配置JVM参数(-Xms512m -Xmx1024m),通过
context.xml设置数据源JNDI,实现应用与数据库配置分离,上线后系统吞吐量提升50%,运维成本显著降低。

独家见解:云环境下的SSM整合,应充分利用云服务提供的托管能力,将数据库、缓存、静态资源等基础设施剥离应用,使应用本身更轻量,专注业务逻辑。
常见问题与解决方案
- Mapper 未绑定:检查
MapperScannerConfigurer的basePackage是否与DAO接口包路径一致,同时确保mapperLocations指向正确(XML映射文件)。 - 事务不生效:确认
@Transactional加在Service实现类上,且applicationContext.xml中已配置<tx:annotation-driven>,避免在Controller层直接调用本类方法。 - 404错误:检查
spring-mvc.xml中<mvc:default-servlet-handler/>是否配置,以及DispatcherServlet的url-pattern是否为。 - 静态资源无法访问:在
web.xml中配置DefaultServlet,或将静态资源托管至CDN(如酷番云对象存储)。
相关问答
问1:SSM整合时,为什么Spring事务在Controller层不生效?
答:事务管理是Spring AOP的应用,通常只作用于Bean方法调用,Controller由SpringMVC容器管理,而事务配置在Spring根容器中,两者层级不同,若在Controller中直接调用Service方法,事务会通过代理生效,但若在Controller内部调用本类方法(比如a方法调用b方法),则不会触发代理,事务失效。解决办法:始终将@Transactional放在Service层,并通过实例调用(而非this.xxx)。
问2:如何优化SSM项目的数据库连接性能?
答:首先选择高性能连接池,如HikariCP;其次设置合理的连接池大小(参考CPU核心数×2+10),开启慢查询日志(MySQL slow_query_log)定位慢SQL,并添加索引,在云部署场景下,推荐使用酷番云RDS,其自动备份、读写分离和一键扩容功能能极大提升数据库可用性与性能。经验:定期分析连接池统计信息(如HikariConfigMXBean),及时调整maxLifetime和idleTimeout避免连接断开。
图片来源于AI模型,如侵权请联系管理员。作者:酷小编,如若转载,请注明出处:https://www.kufanyun.com/ask/697687.html


评论列表(4条)
读了这篇文章,我深有感触。作者对配置的理解非常深刻,论述也很有逻辑性。内容既有理论深度,又有实践指导意义,确实是一篇值得细细品味的好文章。希望作者能继续创作更多优秀的作品!
@老鹿8891:这篇文章写得非常好,内容丰富,观点清晰,让我受益匪浅。特别是关于配置的部分,分析得很到位,给了我很多新的启发和思考。感谢作者的精心创作和分享,期待看到更多这样高质量的内容!
这篇文章写得非常好,内容丰富,观点清晰,让我受益匪浅。特别是关于配置的部分,分析得很到位,给了我很多新的启发和思考。感谢作者的精心创作和分享,期待看到更多这样高质量的内容!
@树树7197:这篇文章的内容非常有价值,我从中学习到了很多新的知识和观点。作者的写作风格简洁明了,却又不失深度,让人读起来很舒服。特别是配置部分,给了我很多新的思路。感谢分享这么好的内容!