恳请spring配置文件逐条详解,详见问题补充。
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<property name="mapperLocations" value="classpath*:com/aspire/nm/sqsjb/umi/mapper/**/*.xml"/>
<property name="typeAliasesPackage" value="com.aspire.nm.sqsjb.umi.domain"/>
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- enable transaction demarcation with annotations -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<!-- enable mapper scanning -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.aspire.nm.sqsjb.umi.mapper"/>
</bean>
<!-- enable component scanning (beware that this does not enable mapper scanning!) -->
<context:component-scan base-package="com.aspire.nm.sqsjb.umi.handler"/>
<context:component-scan base-package="com.aspire.nm.sqsjb.umi.service"/>
知道了这个bean是做什么的了,是因为引入了mybatis-spring.jar。这个bean就是用于创建sqlSessionFactory的。
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
</bean> 展开
逐条解释肯定解释不完,就跟你讲一下事务管理的相关理解吧。
下面是Spring较早时期的一个配置,能体现出一点底层的东西。
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/" />
<property name="user" value="root" />
<property name="password" value="fuhaiwei" />
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mappingResources" value="com/fuhaiwei/domain/domain.xml" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager" >
<property name="dataSource" ref="dataSource" />
</bean>
//看这个,这个是关键,事务管理是靠AOP实现的,下面是一个拦截器。
<bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager" ref="transactionManager" />
<property name="transactionAttributes">
//指定事务传播属性,例如getUser给予只读事务
<props>
<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="add*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
//这个也是关键,指定那些Bean会启动上面的拦截器。
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="interceptorNames" value="transactionInterceptor" />
//指定所有Service结尾的Bean会启用事务管理。
<property name="beanNames" value="*Service" />
</bean>
//现在使用的<tx:annotation-driven transaction-manager="transactionManager"/>
//直接替代了上述两条配置。
从上面的配置可以看出,Spring的事务管理要发挥作用有一些条件。
一:这个类要由Spring来管理,也就是说配置成一个Bean,并且程序中实际使用的必须是由容器注入的。(因为事务管理的实现原理是AOP代理,我们实际使用的UserService对象将是一个代理对象)
二:我们应该告诉Spring,我们想在那些类或者说Bean上启用事务。
三:我们应该告诉Spring,我们想在那些方法上启用事务。(因为AOP代理一般是使用JDK动态代理机制,而JDK想要代理的方法,必须实现于一个接口,所以我们经常发现由Spring管理的项目,其Service和Dao常常都有接口类)
四:我们在Dao中,获取Session时,应该用getCurrentSession()方法,而不是openSession()方法,因为openSession()方法会打开一个全新的Session,且不与线程关联。事务管理器到时候无法获取这个Session也就无法管理事务。而如果使用getCurrentSession()方法,这个方法获取的事务是与线程关联的,到时候事务管理器就可以打开事务,提交事务,或者回滚事务。
五:这是的transactionInterceptor一个片段
public Object invoke(final MethodInvocation invocation) throws Throwable {
//如有必要打开事务。
TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
Object retVal = null;
try {
//运行被代理类的实际方法,也就是我们的Service类的某个方法
retVal = invocation.proceed();
}
catch (Throwable ex) {
//如果抛出异常就回滚事务(默认配置情况下)
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
}
finally {
cleanupTransactionInfo(txInfo);
}
//如果没有异常就提交事务
commitTransactionAfterReturning(txInfo);
return retVal;
}
最后总结,这里面设计到很多个知识点,如什么是AOP,SpringAOP实现的方法是什么,什么是JDK动态代理,什么是Spring自动代理工厂,很多很多,不知道你掌握的情况,所以有问题请追问吧。
http://wenku.baidu.com/view/45dbc60e7cd184254b3535c9.html
配置参考以上内容;
底层实现需要看spring源码。可以下载一个研究下,非三言两语说清楚的啊