此篇接上篇(java架构搭建(三))继续 http://blog.csdn.net/lushuaiyin/article/details/8589938
先看一下applicationContext.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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:configure.properties</value>
</list>
</property>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.query.substitutions">true=1,false=0</prop>
<prop key="hibernate.jdbc.batch_size">25</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">false</prop>
<prop key="hibernate.generate_statistics">false</prop>
<prop key="hibernate.cache.use_query_cache">false</prop>
<prop key="hibernate.cache.region_prefix">direct</prop>
<prop key="hibernate.cache.use_structured_entries">false</prop>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
<prop key="hibernate.query.factory_class">org.hibernate.hql.ast.ASTQueryTranslatorFactory</prop>
<prop key="hibernate.transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</prop>
</props>
</property>
<property name="dataSource" ref="dataSource"/>
<property name="mappingDirectoryLocations">
<list>
<value>classpath:/org/first/config/</value>
<value>classpath:/org/second/config/</value>
</list>
</property>
</bean>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="maxPoolSize" value="${c3p0.maxPoolSize}"/>
<property name="minPoolSize" value="${c3p0.minPoolSize}"/>
<property name="maxIdleTime" value="${c3p0.maxIdleTime}"/>
<property name="maxStatements" value="${c3p0.maxStatements}"/>
<property name="acquireIncrement" value="${c3p0.acquireIncrement}"/>
<property name="idleConnectionTestPeriod" value="${c3p0.idleConnectionTestPeriod}"/>
<property name="driverClass" value="${jdbc.driverClassName}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="transactionProxyTemplate" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true">
<property name="transactionManager" ref="transactionManager"/>
<property name="transactionAttributes">
<props>
<prop key="query*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
<!-- 功能模块的引入 -->
<import resource="classpath:/org/first/config/context_first.xml"/>
<import resource="classpath:/org/second/config/context_second.xml"/>
</beans>
其中
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
即是对事务的配置,他需要注入sessionFactory。
下面还有配置一个事务代理:
<bean id="transactionProxyTemplate" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true">
<property name="transactionManager" ref="transactionManager"/>
<property name="transactionAttributes">
<props>
<prop key="query*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
这个事务代理模板是干嘛用的呢?先看看源码吧:
org.springframework.transaction.interceptor.TransactionProxyFactoryBean
/*jadclipse*/// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
package org.springframework.transaction.interceptor;
import java.util.Properties;
import org.springframework.aop.Pointcut;
import org.springframework.aop.framework.AbstractSingletonProxyFactoryBean;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.transaction.PlatformTransactionManager;
// Referenced classes of package org.springframework.transaction.interceptor:
// TransactionInterceptor, TransactionAttributeSourceAdvisor, TransactionAttributeSource
public class TransactionProxyFactoryBean extends AbstractSingletonProxyFactoryBean
implements BeanFactoryAware
{
public TransactionProxyFactoryBean()
{
}
public void setTransactionManager(PlatformTransactionManager transactionManager)
{
transactionInterceptor.setTransactionManager(transactionManager);
}
public void setTransactionAttributes(Properties transactionAttributes)
{
transactionInterceptor.setTransactionAttributes(transactionAttributes);
}
public void setTransactionAttributeSource(TransactionAttributeSource transactionAttributeSource)
{
transactionInterceptor.setTransactionAttributeSource(transactionAttributeSource);
}
public void setPointcut(Pointcut pointcut)
{
this.pointcut = pointcut;
}
public void setBeanFactory(BeanFactory beanFactory)
{
transactionInterceptor.setBeanFactory(beanFactory);
}
protected Object createMainInterceptor()
{
transactionInterceptor.afterPropertiesSet();
if(pointcut != null)
return new DefaultPointcutAdvisor(pointcut, transactionInterceptor);
else
return new TransactionAttributeSourceAdvisor(transactionInterceptor);
}
private final TransactionInterceptor transactionInterceptor = new TransactionInterceptor();
private Pointcut pointcut;
}
/*
DECOMPILATION REPORT
Decompiled from: D:\ChinaDevelopmentBankJBPM\workSpace\frame\webapp\WEB-INF\lib\spring-tx-3.0.3.RELEASE.jar
Total time: 151 ms
Jad reported messages/errors:
Exit status: 0
Caught exceptions:
*/
通过set方法我们就知道它需呀注入的属性:
setTransactionManager,setTransactionAttributes,setTransactionAttributeSource,setBeanFactory
对比上次对HibernateTemplete,我们可以简单的理解这个类进一步对transactionManager进行了管理。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
事务的使用
context_first.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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<bean id="firstDao" parent="transactionProxyTemplate">
<property name="target">
<bean class=" org.first.dao.impl.FirstDaoImpl">
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>
</property>
<property name="proxyInterfaces">
<value> org.first.dao.FirstDao</value>
</property>
</bean>
</beans>
对涉及事务的api要定义接口和实现类。
FirstDao
package org.first.dao;
import java.util.List;
public interface FirstDao {
public List queryUsers(String realName);
}
FirstDaoImpl
package org.first.dao.impl;
import java.util.List;
import org.base.MyHibernateDao;
import org.first.dao.FirstDao;
public class FirstDaoImpl extends MyHibernateDao implements FirstDao{
public List queryUsers(String realName){
List list=null;
if(realName==null||realName.trim().equals("")){
System.out.println("参数realName为空,查询所有值。");
String hql="select u from LsyUser u ";
list=this.queryListHql(hql);
}else{
String hql="select u from LsyUser u where u.real_name like '%"+realName.trim()+"%'";
list=this.queryListHql(hql);
}
return list;
}
}
然后再spring的配置文件中,如上,把接口类在spring中注册一个bean,class是:parent="transactionProxyTemplate"。
配置属性proxyInterfaces(接口类),target(接口的实现类)。
而接口的实现类需要注入sessionFactory。
上面的文件这样写更清楚:
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<bean id="firstDaoTarget" class="org.first.dao.impl.FirstDaoImpl">
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>
<bean id="firstDao" parent="transactionProxyTemplate">
<property name="target" ref="firstDaoTarget" />
<property name="proxyInterfaces">
<value> org.first.dao.FirstDao</value>
</property>
</bean>
</beans>
再说些废话,上面用到了<bean id="firstDao" parent="transactionProxyTemplate">
这个parent简单说就是继承,如果你再配置一些属性,这些属性就会覆盖默认的属性值。
这样配置:
<bean id="transactionProxyTemplate" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true">
<property name="transactionManager" ref="transactionManager"/>
<property name="transactionAttributes">
<props>
<prop key="query*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
<bean id="firstDao" parent="transactionProxyTemplate">
<property name="target" ref="firstDaoTarget" />
<property name="proxyInterfaces">
<value> org.first.dao.FirstDao</value>
</property>
</bean>
相当于:
<bean id="firstDao" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true">
<property name="transactionManager" ref="transactionManager"/>
<property name="transactionAttributes">
<props>
<prop key="query*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
<property name="target" ref="firstDaoTarget" />
<property name="proxyInterfaces">
<value> org.first.dao.FirstDao</value>
</property>
</bean>
简单理解成继承就可以了,使用parent的好处也就是继承的好处,不用每个bean都去配置属性transactionManager,transactionAttributes。
有了继承,只需要配置一次即可。
----------------------------------------------------------------------------------------------
关于spring事务有哪几种方式,有篇文章介绍的很好。
Spring事务配置的五种方式 http://www.blogjava.net/robbie/archive/2009/04/05/264003.html
----------------------------------------------------------------------------------------------