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

Spring Boot中Groovy DSL如何注入Autowired Bean?

在Groovy DSL中注入Spring管理的SNSService

场景说明

你正在运行一个依赖AWS的Spring Boot Java应用,使用Groovy实现DSL,需要在DSL的send()方法中调用Spring容器里的SNSService Bean。

期望的DSL用法

sendNotification{
  topic 'topic'
  payload 'payload'
  send()
}

现有代码

Groovy DSL类(src/main/groovy)

class SNSDsl{
  String topic
  String payload
  void topic(String topic) {
    this.topic = topic
  }
  void payload(String payload) {
    this.payload = payload
  }

  void send(){
    // 需要调用SNSService的sendNotification方法
  }
}

Spring服务类(src/main/java)

@Named
public class SNSService {
  private final SnsOperations snsOperations;
  
  SNSService (SnsOperations snsOperations){
    this.snsOperations = snsOperations;
  }
  
  public void sendNotification(final String payload, final String topic) {
        SnsNotification<String> notification = SnsNotification.builder(payload)
                .build();
        snsOperations.sendNotification(topic, notification);
    }
}

解决方案

Spring的依赖注入仅对容器内管理的Bean生效,这里提供两种可行方案:

方案一:将SNSDsl声明为Spring Bean,通过构造器注入SNSService

直接把SNSDsl纳入Spring容器管理,利用构造器注入SNSService,就能在send()方法中直接调用:

修改后的SNSDsl:

import org.springframework.stereotype.Component
import javax.inject.Inject

@Component
class SNSDsl{
  String topic
  String payload
  private final SNSService snsService

  // 构造器注入SNSService
  @Inject
  SNSDsl(SNSService snsService) {
    this.snsService = snsService
  }

  void topic(String topic) {
    this.topic = topic
  }

  void payload(String payload) {
    this.payload = payload
  }

  void send(){
    snsService.sendNotification(payload, topic)
  }
}

定义DSL入口方法(Spring Bean),用来启动DSL上下文:

import org.springframework.stereotype.Component
import javax.inject.Inject

@Component
class SNSDslExecutor {
  private final SNSDsl snsDsl

  @Inject
  SNSDslExecutor(SNSDsl snsDsl) {
    this.snsDsl = snsDsl
  }

  void sendNotification(@DelegatesTo(SNSDsl) Closure closure) {
    closure.delegate = snsDsl
    closure.resolveStrategy = Closure.DELEGATE_FIRST
    closure.call()
  }
}

之后在任意Spring管理的Bean中注入SNSDslExecutor,即可使用期望的DSL语法:

// 在某个Spring Bean中
@Inject
private SNSDslExecutor dslExecutor

// 使用DSL
dslExecutor.sendNotification {
  topic 'my-topic'
  payload 'hello-world'
  send()
}

方案二:手动传递SNSService到SNSDsl实例(不将SNSDsl纳入Spring容器)

如果不想让SNSDsl成为Spring Bean,可以在创建DSL实例时手动传入容器中的SNSService:

修改SNSDsl,添加带参数的构造器:

class SNSDsl{
  String topic
  String payload
  private final SNSService snsService

  SNSDsl(SNSService snsService) {
    this.snsService = snsService
  }

  void topic(String topic) {
    this.topic = topic
  }

  void payload(String payload) {
    this.payload = payload
  }

  void send(){
    snsService.sendNotification(payload, topic)
  }
}

定义DSL入口,从Spring容器获取SNSService并传递给SNSDsl:

import org.springframework.stereotype.Component
import javax.inject.Inject

@Component
class SNSDslExecutor {
  private final SNSService snsService

  @Inject
  SNSDslExecutor(SNSService snsService) {
    this.snsService = snsService
  }

  void sendNotification(@DelegatesTo(SNSDsl) Closure closure) {
    def snsDsl = new SNSDsl(snsService)
    closure.delegate = snsDsl
    closure.resolveStrategy = Closure.DELEGATE_FIRST
    closure.call()
  }
}

使用方式和方案一完全一致,注入SNSDslExecutor即可调用DSL。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 22:03:28