@Bean声明上的Spring @Transactional而不是类实现 [英] Spring @Transactional on @Bean declaration instead of class Implementation

查看:155
本文介绍了@Bean声明上的Spring @Transactional而不是类实现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从Spring @Configuration类中配置事务" bean,而不是使用@Transactional注释类实现本身.

I'd like to configure "transactional" beans from my Spring @Configuration class instead of annotating the class implementation itself with @Transactional.

有点像传统的方法,可以从XML文件配置事务建议,但是不需要对我的班级/方法名称的String引用即可创建切入点.

Kind of like the old school way, configuring transactional advice from an XML file, but without needing a String reference to my class/method names to create pointcuts.

原因是bean实现在另一个代码库中,并且它所属的模块不依赖于Spring.阅读:我并没有实例化该bean的源代码,只是实例化了它.该类是最终的,也无法对其进行扩展以将Spring注释添加到子类. 为了简单起见,假设所有方法都必须是事务性的.

The reason is that the bean implementation is in another code base, and the module it belongs to doesn't depend on Spring. Read : I'm not touching the source code of that bean, just instanciating it. The class is final, can't extend it either to add Spring annotations to the child class. Let's say that all the methods must be transactional, for simplicity.

bean实现:

/** This class has no Spring dependency... */
// @Transactional <- which means I can't use this here
public final class ComplexComponentImpl implements ComplexComponent {

    private SomeRepository repo;

    public ComplexComponentImpl(SomeRepository repository) { this.repo = repository }

    public void saveEntities(SomeEntity e1, SomeEntity e2) {
        repo.save(e1);
        throw new IllegalStateException("Make the transaction fail");
    }

我想在配置类中做的事情(并且在我的单元测试中不起作用):

What I want to do in my configuration class (and which doesn't work in my unit test) :

@Configuration
@EnableTransactionManagement
public class ComplexComponentConfig {

    @Bean
    @Transactional // <- Make the bean transactional here
    public ComplexComponent complexComponent() {
        return new ComplexComponentImpl(repository());
    }

    // ...
}

上面的示例实际上是行不通的,因为在运行时没有任何事情发生事务性"处理:即使抛出异常,实体e1​​仍然存在.

The example above doesn't work, indeed, as nothing gets "transactional" at runtime : entity e1 is persisted even though the exception is thrown.

请注意,我的事务管理设置可以很好地与标记为@Transactional的实现类一起很好地工作.

Note that my transaction management setup works works perfectly well with an implementation class marked with @Transactional.

问题:是否可以从@Configuration类声明@Bean事务性事务,或者是否有其他选择考虑上述约束?

Question : Is is it possible to declare @Beans transactional from a @Configuration class, or is there any alternative taking into accounts the constraints above ?

推荐答案

找到了一些内置内容,这些内容是 @Mecon 的答案和 @Erik Gillespie 的答案,且模板有限.

Found something built-in that is the sum of @Mecon's and @Erik Gillespie's answers, with limited boilerplate.

Spring已经提供了 TransactionProxyFactoryBean 可以在任何对象上设置事务代理.许多设置可以重构为某些实用方法:

Spring already provides a TransactionProxyFactoryBean that just sets up a transactional proxy on any object. Much of the setup could be refactored to some utility method :

@Configuration
@EnableTransactionManagement
public class ComplexComponentConfig {

    /** NOT A @Bean, this object will be wrapped with a transactional proxy */
    public ComplexComponent complexComponentImpl() {
        return new ComplexComponentImpl(repository());
    }

    @Bean
    public ComplexComponent complexComponent() {
        TransactionProxyFactoryBean proxy = new TransactionProxyFactoryBean();

        // Inject transaction manager here
        proxy.setTransactionManager(txManager());

        // Define wich object instance is to be proxied (your bean)
        proxy.setTarget(complexComponentImpl());

        // Programmatically setup transaction attributes
        Properties transactionAttributes = new Properties();
        transactionAttributes.put("*", "PROPAGATION_REQUIRED");
        proxy.setTransactionAttributes(transactionAttributes);

        // Finish FactoryBean setup
        proxy.afterPropertiesSet();
        return (ComplexComponent) proxy.getObject;
    }

// ...
}

这篇关于@Bean声明上的Spring @Transactional而不是类实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆