之前项目中使用过SSM框架,但一直没有拿出时间进行深入的研究。
本文主要针对持久层框架Mybatis以及与SpringMVC的整合进行源码分析。
1.整合需要的Jar
Mybatis与Spring整合的主要jar包有两个:mybatis-3.4.0.jar和mybatis-spring-1.3.0.jar
Maven的pom.xml配置文件:
<!-- mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.0</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.0</version>
</dependency>
2.SpringMVC配置文件
Mybatis与SpringMVC的整合是在spring-mybatis.xml配置文件中进行声明。配置文件结构如下:
其中spring-mvc.xml是SpringMVC的配置文件。
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"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
">
<!--自动扫描含有@Service将其注入为bean -->
<context:component-scan base-package="com.*.service" use-default-filters="false">
<context:include-filter type="annotation"
expression="org.springframework.stereotype.Service" />
</context:component-scan>
<!--引入配置属性文件 -->
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:config/jdbc.properties" />
</bean>
<!-- 配置数据源 使用的是Druid数据源 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${driver}" />
<property name="url" value="${url}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
<!-- 初始化连接大小 -->
<property name="initialSize" value="${initialSize}"></property>
<!-- 连接池最大数量 -->
<property name="maxActive" value="${maxActive}"></property>
<!-- 连接池最大空闲 -->
<property name="maxIdle" value="${maxIdle}"></property>
<!-- 连接池最小空闲 -->
<property name="minIdle" value="${minIdle}"></property>
<!-- 获取连接最大等待时间 -->
<property name="maxWait" value="${maxWait}"></property>
</bean>
<!-- weblogic推荐使用jndi连接池 -->
<!--
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>java:comp/env/jdbc/myDatasource</value>
</property>
</bean>
-->
<span style="color:#ff0000;"><strong><!-- spring和MyBatis完美整合,不需要mybatis的配置映射文件 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:mybatis/mybatis-config.xml" />
<!-- 自动扫描entity目录, 省掉Configuration.xml里的手工配置 -->
<property name="mapperLocations" value="classpath*:com/**/mapping/*.xml" />
</bean>
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory" />
</bean>
<!-- DAO接口所在包名,Spring会自动查找其下的类 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.*.dao" />
<property name="sqlSessionTemplateBeanName" value="sqlSession" />
</bean></strong></span>
<!-- 配置事务管理器 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 注解方式配置事物 -->
<!-- <tx:annotation-driven transaction-manager="transactionManager" /> -->
<!-- 拦截器方式配置事物 -->
<tx:advice id="transactionAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="insert*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED" />
<tx:method name="delete*" propagation="REQUIRED" />
<tx:method name="get*" propagation="SUPPORTS" read-only="true"/>
<tx:method name="find*" propagation="SUPPORTS" read-only="true" />
<tx:method name="select*" propagation="SUPPORTS" read-only="true" />
</tx:attributes>
</tx:advice>
<!-- Spring aop事务管理 -->
<aop:config>
<aop:pointcut id="transactionPointcut"
expression="execution(* com..service.impl.*Impl.*(..))" />
<aop:advisor pointcut-ref="transactionPointcut"
advice-ref="transactionAdvice" />
</aop:config>
</beans>
Mybatis与Spring整合部分是红色字体标注的内容。
SqlSessionFactoryBean:datasource、configuration和*mapper.xml的配置信息都会注入到其中。
部分源码:
<span style="font-size:18px;"><span style="color:#ff0000;">private Resource configLocation;</span>
private Configuration configuration;
<span style="color:#ff0000;">private Resource[] mapperLocations;
private DataSource dataSource;</span>
private TransactionFactory transactionFactory;
private Properties configurationProperties;
private SqlSessionFactoryBuilder sqlSessionFactoryBuilder;
private SqlSessionFactory sqlSessionFactory;
private String environment;
private boolean failFast;
private Interceptor[] plugins;
private TypeHandler<?>[] typeHandlers;
private String typeHandlersPackage;
private Class<?>[] typeAliases;
private String typeAliasesPackage;
private Class<?> typeAliasesSuperType;
private DatabaseIdProvider databaseIdProvider;
private Class<? extends VFS> vfs;
private Cache cache;
private ObjectFactory objectFactory;
private ObjectWrapperFactory objectWrapperFactory;</span>
SqlSessionTemplate:实现了SqlSession接口,是Mybatis与数据库进行交互的主要类。
部分源码:
public SqlSessionTemplate(<span style="color:#ff0000;">SqlSessionFactory sqlSessionFactory</span>)
{
this(sqlSessionFactory, sqlSessionFactory.getConfiguration().getDefaultExecutorType());
}
public SqlSessionTemplate(SqlSessionFactory sqlSessionFactory, ExecutorType executorType)
{
this(sqlSessionFactory, executorType,
new MyBatisExceptionTranslator(sqlSessionFactory.getConfiguration
().getEnvironment().getDataSource(), true));
}
public SqlSessionTemplate(SqlSessionFactory sqlSessionFactory, ExecutorType executorType, PersistenceExceptionTranslator exceptionTranslator)
{
Assert.notNull(sqlSessionFactory, "Property 'sqlSessionFactory' is required");
Assert.notNull(executorType, "Property 'executorType' is required");
this.sqlSessionFactory = sqlSessionFactory;
this.executorType = executorType;
this.exceptionTranslator = exceptionTranslator;
this.<strong><span style="color:#ff0000;">sqlSessionProxy</span></strong> = ((DisposableBean)Proxy.newProxyInstance(SqlSessionFactory.class.getClassLoader
(), new Class[] { DisposableBean.class }, new SqlSessionInterceptor(this, null)));
}
可以看出SqlSessionTempalte利用
SqlSessionFactory,也就是上文配置的SqlSessionFactoryBean,最终生成了
SqlSession的实例化对象
sqlSessionProxy,使用的生成方式是Java Proxy机制。
<span style="font-size:24px;"> <span style="color:#ff0000;"><strong>MapperScannerConfigurer:用来自动扫描basePackage目录下的Mapper接口,将每个Mapper接口进行封装生成MapperFactoryBean的实例。</strong></span></span>
至此,Mybatis与SpringMVC已经整合完成。