SSM框架整合
SSM框架中包含Spring,SpringMVC,Mybatis。而Spring与SpringMVC都是Spring Framework的模块,无需整合。只需将Mybatis与Spring整合即可
一、整合关注点
- Spring在web项目中的应用
在web项目启动时,读取applicationContext.mxl配置文件,创建IOC容器 - 使用连接池作为数据源
直连数据源或Spring中的数据源(DriverManagerDataSource),连接效率太低。使用阿里旗下的德鲁伊连接池(druid)作为连接数据源 - Mybatis与Spring的结合
通过Spring的IOC容器管理SqlSessionFactory、mapper接口的代理对象
二、导入依赖
1. Spring依赖
<!-- spring核心包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
<!-- springbean包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
<!-- springcontext包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
<!-- spring表达式包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
<!-- springAOP包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
<!-- springAspects包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
<!-- springJDBC包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
<!-- spring事务包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
<!-- spring对web的支持 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
<!-- springwebMVC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
2. Mybatis依赖
<!-- mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<!-- mybatis的分页助手-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.2</version>
</dependency>
3. Mybatis与Spring整合依赖
<!--Mybatis与spring整合包-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.2</version>
</dependency>
4. 连接池与数据库驱动依赖
<!-- oracle驱动-->
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0</version>
</dependency>
<!-- mysql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
<!--连接池:德鲁伊数据源-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
5. Javaweb环境依赖
<!-- servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- jsp-api -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
<!-- jstl -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
6. 可选插件依赖
<!-- 上传组件包 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<!-- jackson -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.5</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.5</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.5</version>
</dependency>
<!-- hibernate的验证框架-->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.4.1.Final</version>
</dependency>
<!-- log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!-- junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
三、目录结构
src/main/java目录下建立Java软件包结构,src/main/resources目录下存放各种配置文件和资源文件,webapp目录下存放web项目静态资源和WEB-INF目录,其中jsp页面都存放在WEB-INF下
四、配置文件
1. web.xml
1.1 字符编码过滤器
采用Spring中提供的字符编码过滤器CharacterEncodingFilter
<!--字符编码过滤器-->
<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>
1.2 IOC容器的监听器
在web项目启动时,上下文对象ServletContext对象初始化后,读取Spring的配置文件并创建IOC容器对象,最后将其放入到上下文作用域中
采用Spring中提供的ContextLoaderListener监听器
<!-- 上下对象的初始化参数-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/applicationContext*.xml</param-value>
</context-param>
<!-- springIOC容器-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
1.3 前端控制器
<!-- 配置前端控制器-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc/springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
1.4 欢迎页面
<welcome-file-list>
<welcome-file>/WEB-INF/jsp/index.jsp</welcome-file>
</welcome-file-list>
1.5 其他配置
<!-- 通过隐藏域传参解决form表单的PUT与DELETE方式的请求 -->
<filter>
<filter-name>HiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 解决put请求传递参数的问题-->
<filter>
<filter-name>HttpPutFormContentFilter</filter-name>
<filter-class>org.springframework.web.filter.HttpPutFormContentFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HttpPutFormContentFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
2. Mybatis配置文件
以前在mybatis-config.xml中需要加载资源、全局参数、类型别名、分页插件、连接数据库环境、加载映射文件等配置。但与Spring整合后,加载资源、连接数据库环境必须移入Spring中配置,加载映射文件建议移入Spring中(可使用通配符),其他的两者都可。如果将所有内容移入Spring中配置,那么此文件可消失
<configuration>
<!-- 加载资源文件:废除-->
<!-- 全局参数设置-->
<!-- 自定义类型别名-->
<typeAliases>
<package name="com.ssm.entity"/>
</typeAliases>
<!-- 分页插件-->
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor">
<!-- 开启合理化分页-->
<property name="reasonable" value="true"/>
</plugin>
</plugins>
<!-- 连接数据库的环境:废除-->
<!-- 加载映射文件:废除-->
</configuration>
3. Spring配置文件
因Spring中配置过多,可将Spring分成多个文件来进行分别配置。在web.xml中通过通配符一起加载即可(classpath:spring/applicationContext*.xml)
3.1 applicationContext.xml
- 注解扫描
配置:基础包为公共包(com.ssm),并过滤掉@Controller注解
思路:Spring与SpingMVC分开扫描各自的内容,SpingMVC扫描表现层的类(Controller),而Spring扫描其他
<context:component-scan base-package="com.ssm">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
- 数据源
配置:读取db.properties文件,数据源对象采用阿里旗下的德鲁伊连接池,并配置连接数据库的基础信息和连接池的关键信息
<!-- 引入外部资源文件-->
<context:property-placeholder location="classpath:db.properties"/>
<!-- 数据源的配置:德鲁伊连接池-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<!-- 基础配置 -->
<property name="driverClassName" value="${jdbc.oracle.driver}"/>
<property name="url" value="${jdbc.oracle.url}"/>
<property name="username" value="${jdbc.oracle.username}"/>
<property name="password" value="${jdbc.oracle.password}"/>
<!-- 关键配置 -->
<!-- 初始化时建立物理连接的个数。初始化发生在显示调用init方法,或者第一次getConnection时 -->
<property name="initialSize" value="${druid.initialSize}" />
<!-- 最小连接池数量 -->
<property name="minIdle" value="${druid.minIdle}" />
<!-- 最大连接池数量 -->
<property name="maxActive" value="${druid.maxActive}" />
<!-- 配置获取连接等待超时的时间 -->
<property name="maxWait" value="${druid.maxWait}" />
</bean>
- Mybatis
配置:SqlSessionFactory对象bean和mapper接口的代理对象bean
思路:- SqlSessionFactory的最佳使用范围是整个应用运行期间,一旦创建后可以重复使用,通常以单例模式管理。通过mybatis-spring整合包中的SqlSessionFactoryBean来创建一个单例的SqlSessionFactory
- SqlSessionFactoryBean的属性必须配置数据源,可选配加载mybatis的全局配置文件(如果部分内容仍然留在其中),加载mapper映射文件(建议在此配置,可使用统配符批量加载),类型别名,插件等信息
- Mybatis中的mapper代理对象可针对每个接口通过MapperFactoryBean来进行单独配置,仅需告知Dao接口的全限定名即可。缺点:中大型项目中Dao接口过多时,配置量过大,不建议使用
- 通过MapperScannerConfigurer配置mapper代理扫描器可批量配置mapper代理对象,仅需告知Dao接口的存放包名和SqlSessionFactory即可
<!-- mybatis的SqlSessionFactory对象-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 数据源-->
<property name="dataSource" ref="dataSource"/>
<!-- 加载mybatis的全局配置文件-->
<property name="configLocation" value="classpath:mybatis/mybatis-config.xml"/>
<!-- 加载mapper映射文件,可以使用通配符-->
<property name="mapperLocations" value="classpath:mybatis/mapper/*.xml"/>
</bean>
<!-- mapper代理对象 -->
<bean id="empDao" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="com.ssm.dao.EmpDao"/>
</bean>
<bean id="deptDao" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="com.ssm.dao.DeptDao"/>
</bean>
<!-- mapper代理对象的扫描器-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 扫描基础包-->
<!-- 如果有多个基础包,可以使用逗号分隔-->
<property name="basePackage" value="com.ssm.dao" />
<!-- 注入SqlSessionFactory-->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>
3.2 applicationContext-tx.xml
- 事务管理配置文件
配置:事务管理器对象,事务,事务属性,事务切入点
思路:- 事务相关配置放在此文件中,与其他配置分离,减少配置文件臃肿的情况,便于后期维护
- 持久层使用Mybatis框架,事务管理器采用JDBC的事务管理器即可(DataSourceTransactionManager),并注入数据源对象
- 事务属性根据不同的需求选择更佳合理的配置
- 事务切入点将事务通过AOP的方式应用在指定的切点表达式中
<!-- 事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入数据源-->
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 事务-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!-- 配置事务属性-->
<tx:attributes>
<tx:method name="insert*" propagation="REQUIRED" isolation="READ_COMMITTED"/>
<tx:method name="save*" propagation="REQUIRED" isolation="READ_COMMITTED"/>
<tx:method name="add*" propagation="REQUIRED" isolation="READ_COMMITTED"/>
<tx:method name="update*" propagation="REQUIRED" isolation="READ_COMMITTED"/>
<tx:method name="edit*" propagation="REQUIRED" isolation="READ_COMMITTED"/>
<tx:method name="del*" propagation="REQUIRED" isolation="READ_COMMITTED"/>
<tx:method name="delete*" propagation="REQUIRED" isolation="READ_COMMITTED"/>
<tx:method name="find*" propagation="SUPPORTS" read-only="true"/>
<tx:method name="query*" propagation="SUPPORTS" read-only="true"/>
<tx:method name="get*" propagation="SUPPORTS" read-only="true"/>
<tx:method name="select*" propagation="SUPPORTS" read-only="true"/>
<tx:method name="list*" propagation="SUPPORTS" read-only="true"/>
<!-- 事务属性应用于方法的名称,*表示所有方法-->
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
<!-- 事务切入点-->
<aop:config>
<aop:pointcut id="exp" expression="execution(* com.ssm.service.*Impl.*(..))"/>
<!-- 将切点表达式与事务建立联系-->
<aop:advisor advice-ref="txAdvice" pointcut-ref="exp" />
</aop:config>
4. SpringMVC配置文件
- 注解扫描
配置:基础包为表现层的软件包
思路:SpingMVC仅负责扫描表现层的类(Controller)
解析:SpingMVC中的注解扫描也是将扫描到的对象放入到IOC容器中。当web项目启动后首先配置的是Spring容器的初始化,然后是SpringMVC的前端控制器(DispatchServlet),当配置完DispatchServlet后会在Spring容器中创建一个新的容器。其实这是两个容器,Spring作为父容器,SpringMVC作为子容器(如下图),SpringMVC子容器中的对象是可以访问Spring父容器中的对象,但父容器中的对象无法访问子容器中的对象。通常在Service中注入Dao,接着在Controller里注入Service,这就意味这作为SpringMVC的子容器是可以访问父容器Spring对象的,如果把Controller注入到Service中肯定是不行的。假设将Dao,Serive,Controller都放入同一个容器中,那么对象之间的依赖注入是没有问题了,但必须都在SpringMVC的子容器(在SpringMVC中扫描全部)。如果Dao,Serive,Controller都放在Spring的父容器中(在Spring中扫描全部),而这时的SpringMVC容器中没有Controller对象,所以加载处理器适配器的时候就会找不到映射的Controller对象,因此在页面上就会出现404的错误。
<context:component-scan base-package="com.ssm.controller"/>
- 注解驱动
<mvc:annotation-driven conversion-service="conversionService"/>
- 视图解析器
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
- 格式化与类型转换服务
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.ssm.util.DateConverter"/>
</set>
</property>
</bean>
- 静态资源处理
<mvc:default-servlet-handler/>
- 其他配置
<!-- 文件上传解析器-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 设置上传文件大小,单位为字节,大小为100MB -->
<property name="maxUploadSize" value="104857600"/>
<!-- 设置上传的字符编码-->
<property name="defaultEncoding" value="utf-8"/>
<!-- 设置缓存大小,大小为10KB-->
<property name="maxInMemorySize" value="10240"/>
</bean>
<!-- 配置拦截器-->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<!-- 排除不拦截路径-->
<mvc:exclude-mapping path="/login"/>
<bean class="com.ssm.intercepor.LoginInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
小,单位为字节,大小为100MB -->
<property name="maxUploadSize" value="104857600"/>
<!-- 设置上传的字符编码-->
<property name="defaultEncoding" value="utf-8"/>
<!-- 设置缓存大小,大小为10KB-->
<property name="maxInMemorySize" value="10240"/>
</bean>
<!-- 配置拦截器-->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<!-- 排除不拦截路径-->
<mvc:exclude-mapping path="/login"/>
<bean class="com.ssm.intercepor.LoginInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>