You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring中如何在Rest方法内动态实例化事务型组件?

解决方案

要在每次调用接口时生成TestComponent的新实例,同时保证@Transactional注解生效,你可以通过以下步骤实现:

1. 修改TestComponent的作用域为原型

首先将TestComponent的作用域设置为原型(prototype),这样Spring每次请求该Bean时都会创建新实例:

@Scope("prototype")
@Component
@Transactional
public class TestComponent {
    private EntityManager entityManager;
    private UUID randomUUID;

    @Autowired
    public TestComponent(EntityManager entityManager) {
        this.entityManager = entityManager;
        this.randomUUID = UUID.randomUUID();
    }

    public String uuid() {
        // entityManager transactional stuff
        return randomUUID.toString();
    }
}

2. 方式一:使用Provider<TestComponent>获取新实例

在RestController中注入Provider<TestComponent>,每次调用get()方法即可获取新的TestComponent实例,Spring会自动处理事务逻辑:

@Validated
@RestController
@RequestMapping("test")
public class TestController {

    private final Provider<TestComponent> testComponentProvider;

    @Autowired
    public TestController(Provider<TestComponent> testComponentProvider) {
        this.testComponentProvider = testComponentProvider;
    }

    @GetMapping
    public String test() {
        TestComponent component = testComponentProvider.get();
        return component.uuid();
    }
}

3. 方式二:使用@Lookup方法注入

通过@Lookup注解实现方法级的Bean注入,Spring会动态生成代理方法,每次调用都会返回新的原型实例:

@Validated
@RestController
@RequestMapping("test")
public class TestController {

    @GetMapping
    public String test() {
        TestComponent component = createTestComponent();
        return component.uuid();
    }

    // Spring会代理该方法,返回新的TestComponent实例
    @Lookup
    protected TestComponent createTestComponent() {
        // 此处仅为占位实现,Spring会自动替换
        return null;
    }
}

为什么之前的尝试无效?

  • 直接new TestComponent():该实例不受Spring管理,@Transactional注解无法生效,EntityManager也无法自动注入。
  • ApplicationContext.getBean():默认情况下TestComponent是单例作用域,所以每次获取同一个实例;若已设置原型作用域,虽然能获取新实例,但直接依赖ApplicationContext不符合依赖注入的设计原则。

内容的提问来源于stack exchange,提问作者Emax

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 10:25:35