如何进行自注入 Spring Boot 3+,以便通过代理并应用事务行为

问题描述 投票:0回答:1

我想在我的服务中创建一个自引用,以便我可以使用它来通过 Spring 的代理并应用事务行为。

@RequiredArgsConstructor
public class Service {
  @Lazy private final Service self;

  public void foo() {
    self.bar();
  }

  @Transactional
  public void bar() {
    // do some transactional stuff
  }
}

我也想这样做,以符合

java:S6809

A method annotated with Spring’s @Async or @Transactional annotations will not work as expected if invoked directly from within its class.
This is because Spring generates a proxy class with wrapper code to manage the method’s asynchronicity (@Async) or to handle the transaction (@Transactional). However, when called using this, the proxy instance is bypassed, and the method is invoked directly without the required wrapper code.

问题是我不能这样做,否则我在启动时会收到错误

The dependencies of some of the beans in the application context form a cycle:
Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true.
  • 我用过
    @Lazy
  • 我在
    lombok.copyableAnnotations += org.springframework.context.annotation.Lazy
    中使用了
    lombok.config

spring.main.allow-circular-references
设置为 true 是在 Spring 中进行自注入的唯一解决方案吗?

(一些参考资料:https://medium.com/javarevisited/spring-transactional-mistakes-everyone-did-31418e5a6d6b

java spring dependency-injection spring-transactions
1个回答
0
投票

您可以尝试用

TransactionTemplate
代替
@Transactional

@RequiredArgsConstructor
class MyService {
    @Lazy
    private final MyService self;
    private final TransactionTemplate transactionTemplate;


    public void foo() {
        self.bar();
    }

    public void bar() {
        transactionTemplate.executeWithoutResult(ts -> {
            // do tx stuff
        });
    }
}

https://docs.spring.io/spring-framework/reference/data-access/transaction/programmatic.html

© www.soinside.com 2019 - 2024. All rights reserved.