如何通过工厂方法创建事务代理?

时间:2016-01-26 13:02:37

标签: java spring proxy

我有一个通过factory-method创建的spring bean,我还需要使用@Transactional工具。所以,当我按如下方式创建它时:

<bean id="myBean" class="pack.age.MyBean" factory-method="create">
    <constructor-arg ref="someBean" />
</bean>

其中

public class MyBean implements MyInterface{

    private final SomeBean someBean;

    public static MyInterface create(SomeBean someBean){
        MyBean retVal = new MyBean(someBean);
        //Create a thread and run it.
        //Do some other job that doesn't suit for constructor
    }

    private MyBean(SomeBean someBean){
         this.someBean = someBean;
    }
}

现在,当我尝试将bean注入其他bean时:

public class MyAnotherBean{

    private MyInterface myInterface;


    public boid setMyInterface(MyInterface myInterface){
        this.myInterface = myInterface;
    }
}

声明为

<bean id="myAnotherBean" class="pack.age.MyAnotherBean">
    <property name="myInterface" ref="myBean" />
</bean>

注入了实际的myBean实例, 不是代理 。由于它不是代理,我无法使用Spring @Transactional工具。

如何通过静态factory-method构建对象时注入代理?

1 个答案:

答案 0 :(得分:1)

在这种情况下,只需在beans声明下启用事务注释即可:

<tx:annotation-driven transaction-manager="txManager"/>
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <!-- (this dependency is defined somewhere else) -->
    <property name="dataSource" ref="dataSource"/>
</bean>

但如果没有,你可以尝试以声明方式启用事务:

<tx:advice id="txAdvice" transaction-manager="txManager">
    <!-- the transactional semantics... -->
    <tx:attributes>
        <!-- all methods starting with 'get' are read-only -->
        <tx:method name="get*" read-only="true"/>
        <!-- other methods use the default transaction settings (see below) -->
        <tx:method name="*"/>
    </tx:attributes>
</tx:advice>

<!-- ensure that the above transactional advice runs for any execution
    of an operation defined by the MyInterface interface -->
<aop:config>
    <aop:pointcut id="myBeanOperation" expression="execution(* x.y.service.MyInterface.*(..))"/>
    <aop:advisor advice-ref="txAdvice" pointcut-ref="myBeanOperation"/>
</aop:config>