整合SpringMVC和Spring和Hibernate
新建一个maven项目sshweb:
SpringMVC和Spring:5.0.8
Hibernate:5.2.17.Final
mysql驱动:5.1.46
一、在 pom.xml 中导入包的依赖
<dependencies>
<!-- spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
<!-- servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>
<!-- log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<!-- taglibs -->
<dependency>
<groupId>org.apache.taglibs</groupId>
<artifactId>taglibs-standard-spec</artifactId>
<version>1.2.5</version>
<type>bundle</type>
</dependency>
<dependency>
<groupId>org.apache.taglibs</groupId>
<artifactId>taglibs-standard-impl</artifactId>
<version>1.2.5</version>
<type>bundle</type>
</dependency>
<!-- hibernate -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.2.17.Final</version>
</dependency>
<!-- hibernate-c3p0包含c3p0 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-c3p0</artifactId>
<version>5.2.17.Final</version>
</dependency>
<!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.46</version>
</dependency>
<!--以上为必须基本包,以下为功能需要架包 -->
<!-- JSR-303后台校验, 官方参考实现是Hibernate Validator -->
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.10.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator-annotation-processor</artifactId>
<version>6.0.10.Final</version>
</dependency>
<!--jackson -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.6</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.6</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.6</version>
</dependency>
<!-- commons-fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
<!-- junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
</plugin>
</plugins>
</build>
二、web.xml中配置,将Spring(并整合Hibernate)和SpringMVC整合起来
1、在web.xml中配置 contextLoaderListener ,并加入spring的配置文件 applicationContext.xml 。这样可以把service、dao、事务、缓存、以及和其它框架的整合放到spring的配置文件里面。
2、在web.xml中配置 DispatcherServlet,并加入SpringMVC的的配置文件 springmvc.xml,
这时,两个配置文件中扫描的包有重合的时候出现某些bean会被初始化2次的问题:
解决方案:在扫描包的子节点下配置 exclude-filter 和 include-filter (见配置文件),
SpringMVC只扫描Controller和ControllerAdvice:
Spring排除扫描Controller和ControllerAdvice:
1)web.xml :
<!--解决中文乱码的filter一定要放在最前面 -->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<!-- 配置encoding,告诉我们指定的编码格式 -->
<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>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 1. 指定applicationContext.xml配置文件的位置和名称及ContextLoaderListener -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring.xml</param-value>
</context-param>
<!-- 开启初始化IOC容器的监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 2. 指定springmvc.xml.xml配置文件的位置和名称及DispatcherServlet -->
<servlet>
<servlet-name>springDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- 指定url地址 -->
<servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--
/: 根目录下的所有url地址, 但是不包括servlet
/*: 根目录下的所有url地址, 包括servlet, 一般用在filter配置
-->
<!-- hiddenHttpMethodFilter过滤器处理REST:将指定的POST请求转化为put请求或delele请求 -->
<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>
<!-- 解决懒加载异常过滤器: session生命周期和requset请求的生命周期绑定 -->
<filter>
<filter-name>openSessionInViewFilter</filter-name>
<filter-class>org.springframework.orm.hibernate5.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>openSessionInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
2)spring.xml: 并整合Hibernate (orm使用*.hbm.xml),
使用JPA 注解映射实体类:https://mp.csdn.net/postedit/83475268
<!-- 1. 导入源属性文件 -->
<context:property-placeholder location="classpath:application.properties" />
<!-- c3p0 连接池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!-- 类似EL表达式取资源文件的值 -->
<property name="driverClass" value="${jdbc.driverClass}"></property>
<property name="jdbcUrl" value="${jdbc.url}"></property>
<property name="user" value="${jdbc.user}"></property>
<property name="password" value="${jdbc.password}"></property>
<property name="initialPoolSize" value="${c3p0.initialPoolSize}"></property>
<property name="acquireIncrement" value="${c3p0.acquireIncrement}"></property>
<property name="maxPoolSize" value="${c3p0.maxPoolSize}"></property>
<property name="minPoolSize" value="${c3p0.minPoolSize}"></property>
<property name="maxStatements" value="${c3p0.maxStatements}"></property>
<property name="maxStatementsPerConnection" value="${c3p0.maxStatementsPerConnection}"></property>
</bean>
<!-- 2. 整合Hibernate, 配置Hibernate的Sessionfactory实例 -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<!-- 数据源 -->
<property name="dataSource" ref="dataSource"></property>
<!-- orm映射文件 *.hbm.xml -->
<property name="mappingLocations" value="classpath:cn/jq/sshweb/model/*.hbm.xml"></property>
<!-- hibernate配置信息 -->
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
</props>
</property>
</bean>
<!-- 3. 使用注解驱动 配置包扫描(使用默认的 Filter 进行扫描,不包含springmvc要扫的包) -->
<context:component-scan base-package="cn.jq.sshweb">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
<context:exclude-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
</context:component-scan>
<!-- 配置spring的hibernate5声明事务管理器 -->
<bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<!-- 开启事务注释 @Transactional -->
<!--<tx:annotation-driven transaction-manager="transactionManager" /> -->
<!-- 配置事务通知 -->
<tx:advice id="tsAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="get*" read-only="true"/>
<tx:method name="find*" read-only="true"/>
<tx:method name="select*" read-only="true"/>
<tx:method name="*" read-only="false"/>
</tx:attributes>
</tx:advice>
<!-- 配置事务切入点 -->
<aop:config>
<aop:pointcut expression="execution(* cn.jq.sshweb.service.*.*(..))" id="txPointcut"/>
<aop:advisor advice-ref="tsAdvice" pointcut-ref="txPointcut"/>
</aop:config>
<!-- 4. 配置spring的jdbcTemplate -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
3)springmvc.xml :
<!-- 简写形式: 默认会帮我们注册默认处理请求,参数和返回值的类-->
<mvc:annotation-driven />
<!-- 让springmvc自动识别静态资源文件: js, css, 图片等 -->
<mvc:default-servlet-handler/>
<!-- 1. 使用注解驱动 配置包扫描(不使用默认的 Filter 进行扫描,包含springmvc要扫的包) -->
<context:component-scan base-package="cn.jq.sshweb" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
<context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
</context:component-scan>
<!-- 2. 配置springmvc视图解析器ViewResolver -->
<bean id="" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/view/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<mvc:view-controller path="/" view-name="index"/>
<!-- 配置自定义的数据转换器,并注入到springmvc容器中-->
<!-- 配置文件上传的解析器:-->
<!-- 配置拦截器: -->
<!-- 配置全局异常处理的处理器: -->
三、需要的配置文件
1)application.properties :
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/sshweb?useUnicode=true&characterEncoding=utf8&useSSL=true
jdbc.user=root
jdbc.password=123456
c3p0.initialPoolSize=5
c3p0.acquireIncrement=5
c3p0.maxPoolSize=20
c3p0.minPoolSize=5
c3p0.maxStatements=200
c3p0.maxStatementsPerConnection=5
hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
hibernate.show_sql=true
hibernate.format_sql=true
hibernate.hbm2ddl.auto=update
2)log4j.properties :
log4j.rootLogger = debug,stdout, D
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.Threshold = INFO
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p %m%n
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = ./log4j.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern=%d %p %m%n
四、 运行项目测试
新建一个UserController 类, 只会初始化一次。
@Controller
public class UserController {
public UserController() {
System.out.println("UserController 构造器初始化---");
}
}
到此SSH整合就搞定了,小项目目录如下