从基于配置的服务 bean 切换到基于注释的服务 bean 时的 TransactionProxyFactoryBean

Posted

技术标签:

【中文标题】从基于配置的服务 bean 切换到基于注释的服务 bean 时的 TransactionProxyFactoryBean【英文标题】:TransactionProxyFactoryBean when switching from configuration-based Service beans to annotation based service beans 【发布时间】:2009-10-27 17:01:39 【问题描述】:

我读到了使用

  <context:component-scan base-package="tld.mydomain.business">
      <context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/>
  </context:component-scan>

并用 @Service("myService") 注释我的服务 bean,我觉得很好,我会这样做,因为我已经用我的控制器这样做了。我通常的服务 bean 配置看起来像

  <bean id="userService" parent="txProxyTemplate">
    <property name="target">
      <bean class="tld.mydomain.business.UserServiceImpl"/>
    </property>
    <property name="proxyInterfaces" value="tld.mydomain.business.UserService"/>
  </bean>

既然我生成了它们,我如何将它们包装在诸如 TransactionProxyFactoryBean 之类的 Hibernate 代理中?还是有更好的方法来做到这一点?

我还没有完全使用@Repository,这是必需的吗?

干杯

尼克

【问题讨论】:

【参考方案1】:

在现代 Spring 应用程序中不鼓励使用 TransactionProxyFactoryBean,尽管它仍然有效。现在的典型方法是使用 @Transactional 注释类,然后将此元素粘贴到您的应用程序上下文文件中:

<tx:annotation-driven transaction-manager="txManager"/>

这个和其他策略在参考文档中有很深入的discussed,甚至还有一个关于TransactionProxyFactoryBean的旁注。

【讨论】:

非常感谢,我关注了一本关于 Spring 2 的书,其中推荐了 TransactionProxyFactoryBean,我现在看到我应该更仔细地查看文档。不过,只是快速跟进:这似乎仅适用于只有一个事务管理器的场景。不幸的是,我有两个,因为我需要使用两个不同的数据库。使用 TransactionProxyFactoryBean 没有问题。表 9.2 和 9.3 似乎并不表明我可以 嗯,当我这样做时,访问我的服务时出现以下异常:org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'org.springframework.transaction.interceptor.TransactionInterceptor#0'必须是 [org.aopalliance.aop.Advice] 类型,但实际上是 [org.springframework.transaction.interceptor.TransactionInterceptor] 类型 会不会是@Service("myService") 和@Transactional 注解冲突了? 在这个 bug 上花费了数小时后,我决定将问题作为一个单独的问题发布,而不是在此线程中跟进。这是链接:***.com/questions/1636063/…【参考方案2】:

不需要

&lt;context:include-filter type="annotation"expression="org.springframework.stereotype.Service"/&gt;

一旦在基础包中找到@Service, @Repository, @Component...,Spring 就会注册。

就像@Rob 所说,要么使用@Transactional&lt;aop:config&gt;...&lt;/aop:config&gt; 在服务级别处理您的交易。

【讨论】:

感谢您的提示,我已经删除了多余的杂物。您对我为什么会出现上面的 BeanNotOfRequiredTypeException 有什么建议吗?或者如何处理多个事务管理器?我从文档中看到,我可以使用 给出不同的建议,但在我看来,这仍然只存在于一个事务管理器中? 通常BeanNotOfRequiredType 当您注入错误类型的 bean 但除非您发布堆栈跟踪,否则我无法进一步发言。那么你只需要1个PlatformTransactionManager,除非你有2个差异DataSource,否则不需要2个。【参考方案3】:

如果您有两个不同的资源需要在同一个事务中,那么您将需要使用 JTA。请参阅我对先前问题here 的回答。您的配置需要如下所示:

<tx:annotation-driven transaction-manager="txManager"/>

<bean id="txManager" 
    class="org.springframework.transaction.jta.JtaTransactionManager">
    <property name="transactionManagerName" value="appserver/jndi/path" />
</bean>

appserver/jndi/path 需要替换为应用服务器附带的 JTA 事务管理器的 JNDI 路径(尽管您也可以使用独立的 JTA 事务管理器,例如 JOTM)。 2.5.x API 中提到的典型路径是:

“java:comp/UserTransaction”用于 Resin 2.x、Oracle OC4J (Orion)、JOnAS (JOTM)、BEA WebLogic Resin 3.x 的“java:comp/TransactionManager” GlassFish 的“java:appserver/TransactionManager” “java:pm/TransactionManager”用于 Borland Enterprise Server 和 Sun Application Server(Sun ONE 7 及更高版本) JBoss 应用服务器的“java:/TransactionManager”

【讨论】:

您好 Toolkit,非常感谢您的意见。当我使用 TransactionProxyFactoryBean 时,我已经能够绕过它,因为将它们保持在同一个事务中并不是绝对必要的,我也可以有两个,其中一个是只读的。这就是为什么我问说什么交易去哪里。将它们合二为一似乎是最好的主意。但两者都是 JDBC 连接,我没有使用过 JNDI。但是我会在早上阅读你的建议(现在这里是午夜)干杯-Nik

以上是关于从基于配置的服务 bean 切换到基于注释的服务 bean 时的 TransactionProxyFactoryBean的主要内容,如果未能解决你的问题,请参考以下文章

Spring框架bean的配置:基于注解的配置,Autowired 自动装配 Bean,泛型依赖注入

5.spring:注解配置 Bean

java怎么配置spring的bean

基于Spring DM管理的Bundle获取Spring上下文对象及指定Bean对象

如何配置和传输 MySQL(使用登录凭据)从 XAMPP 本地网络服务器到基于 Hostgator/Linux 的托管服务器?

Spring之基于注解配置