关于TransactionProxyFactoryBean

       	   <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource">
<ref local="dataSource"></ref>
</property>
</bean>
<bean id="baseTransactionProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref local="transactionManager" />
</property>
<property name="transactionAttributes">
<props>
<prop key="update">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>

<bean id="service" parent="baseTransactionProxy">
<property name="target">
<ref local="service_target" />
</property>
</bean>

<bean id="service_target" class="test.spring.transaction.TestService" />


以上是spring声明式事务的一种方式。

当调用context.getBean("service"),代理的生成过程是怎样的?


TransactionProxyFactoryBean的父类AbstractSingletonProxyFactoryBean中有个方法afterPropertiesSet,在这个方法中(afterPropertiesSet方法是spring在初始化bean的的过程中,会调用该方法,通过实现该方法,为bean提供一些特定的行为。),会产生一个代理。
	public void afterPropertiesSet() {
if (this.target == null) {
throw new IllegalArgumentException("Property 'target' is required");
}
if (this.target instanceof String) {
throw new IllegalArgumentException("'target' needs to be a bean reference, not a bean name as value");
}
if (this.proxyClassLoader == null) {
this.proxyClassLoader = ClassUtils.getDefaultClassLoader();
}

ProxyFactory proxyFactory = new ProxyFactory();

if (this.preInterceptors != null) {
for (Object interceptor : this.preInterceptors) {
proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(interceptor));
}
}

// Add the main interceptor (typically an Advisor).
proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(createMainInterceptor()));

if (this.postInterceptors != null) {
for (Object interceptor : this.postInterceptors) {
proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(interceptor));
}
}

proxyFactory.copyFrom(this);

TargetSource targetSource = createTargetSource(this.target);
proxyFactory.setTargetSource(targetSource);

if (this.proxyInterfaces != null) {
proxyFactory.setInterfaces(this.proxyInterfaces);
}
else if (!isProxyTargetClass()) {
// Rely on AOP infrastructure to tell us what interfaces to proxy.
proxyFactory.setInterfaces(
ClassUtils.getAllInterfacesForClass(targetSource.getTargetClass(), this.proxyClassLoader));
}

this.proxy = proxyFactory.getProxy(this.proxyClassLoader);
}



spring 在bean生成之后,判断bean是否为FactoryBean,具体在AbstractBeanFactory的
getObjectForBeanInstance中。

如果是FactoryBean,将使用FactoryBeanRegistrySupport类(DetautListableFactory的父类)中的doGetObjectFromFactoryBean方法

private Object doGetObjectFromFactoryBean(
final FactoryBean factory, final String beanName, final boolean shouldPostProcess)
throws BeanCreationException {

Object object;
try {
if (System.getSecurityManager() != null) {
AccessControlContext acc = getAccessControlContext();
try {
object = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
public Object run() throws Exception {
return factory.getObject();
}
}, acc);
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
object = factory.getObject();
}
}
catch (FactoryBeanNotInitializedException ex) {
throw new BeanCurrentlyInCreationException(beanName, ex.toString());
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
}


// Do not accept a null value for a FactoryBean that's not fully
// initialized yet: Many FactoryBeans just return null then.
if (object == null && isSingletonCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(
beanName, "FactoryBean which is currently in creation returned null from getObject");
}

if (object != null && shouldPostProcess) {
try {
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Post-processing of the FactoryBean's object failed", ex);
}
}

return object;
}

可以看到该方法中
object = factory.getObject();

调用了FactoryBean的getObjcet。

那么从AbstractSingletonProxyFactoryBean(TransactionProxyFactoryBean的父类)中的getObject方法中看到
	public Object getObject() {
if (this.proxy == null) {
throw new FactoryBeanNotInitializedException();
}
return this.proxy;
}

方法返回了上面(afterPropertiesSet方法中生成的代理)产生的代理类。

因此getBean获取的是一个代理(jdk代理或cgLib代理)。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当使用Hibernate和Spring的事务管理器时,可以使用TransactionProxyFactoryBean和DataSourceTransactionManager两个类。在配置时,需要在Spring的配置文件中定义TransactionProxyFactoryBean,并将其与DataSourceTransactionManager关联。 具体配置步骤如下: 1. 配置数据源 在Spring的配置文件中,需要配置数据源。例如: ```xml <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/test"/> <property name="username" value="root"/> <property name="password" value="root"/> </bean> ``` 2. 配置事务管理器 在Spring的配置文件中,需要配置DataSourceTransactionManager作为事务管理器。例如: ```xml <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> ``` 3. 配置TransactionProxyFactoryBean 在Spring的配置文件中,需要配置TransactionProxyFactoryBean,它用于创建代理对象并将事务管理器与代理对象关联。例如: ```xml <bean id="userService" class="com.example.UserService"> <property name="userDao" ref="userDao"/> </bean> <bean id="userDao" class="com.example.UserDao"> <property name="sessionFactory" ref="sessionFactory"/> </bean> <bean id="txProxyTemplate" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> <property name="transactionManager" ref="transactionManager"/> <property name="target" ref="userService"/> <property name="proxyInterfaces" value="com.example.UserService"/> <property name="transactionAttributes"> <props> <prop key="*">PROPAGATION_REQUIRED</prop> </props> </property> </bean> ``` 在上面的配置中,txProxyTemplate是一个TransactionProxyFactoryBean对象,它将userService作为目标对象,并将其与transactionManager关联。同时,它还指定了代理对象要实现的接口和事务属性。 4. 使用代理对象 在使用事务时,需要使用TransactionProxyFactoryBean创建的代理对象。例如: ```java ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml"); UserService userService = (UserService) context.getBean("txProxyTemplate"); userService.updateUser(user); ``` 以上就是Hibernate和Spring同时使用TransactionProxyFactoryBean和DataSourceTransactionManager事务管理器的配置方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值