如何访问Grails3中普通groovy类中的数据源?

如何访问Grails3中普通groovy类中的数据源?,grails,grails-3.3,Grails,Grails 3.3,我试图从普通Groovy类(没有服务)内部运行sql代码。 在Grails 2中,我可以通过以下方式访问数据源: public GroovyClass() { def ctx = ServletContextHolder.servletContext.getAttribute(GrailsApplicationAttributes.APPLICATION_CONTEXT) def dataSource = ctx.getBean('dataSource') sql =

我试图从普通Groovy类(没有服务)内部运行sql代码。 在Grails 2中,我可以通过以下方式访问数据源:

 public GroovyClass() {
    def ctx = ServletContextHolder.servletContext.getAttribute(GrailsApplicationAttributes.APPLICATION_CONTEXT)
    def dataSource = ctx.getBean('dataSource')
    sql = new Sql(dataSource)
 }

迁移到Grails3.3.8后,代码不再工作。Grails3.3.8中正确的方法是什么?

我刚刚测试了这个,它似乎给出了数据源

def ds = Holders.grailsApplication.mainContext.getBean('dataSource')
println "DataSource: ${ds}"  ---> DataSource: org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy@5e91ade8

没有对它进行任何操作,但看起来不错。

我刚刚测试了这个,它似乎给出了数据源

def ds = Holders.grailsApplication.mainContext.getBean('dataSource')
println "DataSource: ${ds}"  ---> DataSource: org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy@5e91ade8
“好莱坞原则”说“不要打电话给我们,我们会打电话给你”,这就是依赖注入的意义所在。在您的情况下,不要去获取
数据源
,而是将
数据源
交给您

有很多方法可以做到这一点。请参阅上的项目

运行应用程序并向发送请求,这将验证所有3种方法都有效

有其他方法可以做到这一点,但我希望上述其中之一将对您有所帮助

祝你好运

好莱坞原则说“不要打电话给我们,我们会打电话给你”,这就是依赖注入的意义所在。在您的情况下,不要去获取
数据源
,而是将
数据源
交给您

有很多方法可以做到这一点。请参阅上的项目

运行应用程序并向发送请求,这将验证所有3种方法都有效

有其他方法可以做到这一点,但我希望上述其中之一将对您有所帮助


祝你好运

下面被接受的答案是个坏主意。我不主张这样做。正确的答案需要更多地了解与这个groovy类交互的上下文。您是否从控制器与之交互?服务?独自创立还有别的吗?@JeffScottBrown来自Grails服务下面被接受的答案是个坏主意。我不主张这样做。正确的答案需要更多地了解与这个groovy类交互的上下文。您是否从控制器与之交互?服务?独自创立还有别的吗?@JeffScottBrown来自Grails服务,不鼓励使用
Holders
访问bean。不鼓励使用
Holders
访问bean。这看起来可能比实际情况更复杂,部分原因是上面显示了3种不同的解决方案。您真正要做的就是将类的一个实例添加到Spring应用程序上下文中(在
参考资料.groovy
中),这样它就可以接受DI,然后在您想使用它的任何地方注入该bean。在上面的示例中,这是
SomeService
。感谢您的详尽回答,非常有帮助且富有教育意义。这看起来可能比实际情况更复杂,部分原因是上面显示了3种不同的解决方案。您真正要做的就是将类的一个实例添加到Spring应用程序上下文中(在
参考资料.groovy
中),这样它就可以接受DI,然后在您想使用它的任何地方注入该bean。在上面的示例中,这是
SomeService
。感谢您的详细回答,非常有帮助和有教育意义。
// src/main/groovy/ascudemo/SecondGroovyClass.groovy
package ascudemo.helpers

import groovy.sql.Sql
import groovy.util.logging.Slf4j

import javax.annotation.PostConstruct
import javax.sql.DataSource

@Slf4j
class SecondGroovyClass {
    DataSource dataSource
    Sql sql

    void logSomeInfo() {
        // both have been initialized
        log.debug "dataSource: ${dataSource}"
        log.debug "sql: ${sql}"
    }

    @PostConstruct
    void initSql() throws Exception {
        sql = new Sql(dataSource)
    }
}
// src/main/groovy/ascudemo/SecondGroovyClass.groovy
package ascudemo.helpers

import groovy.sql.Sql
import groovy.util.logging.Slf4j
import org.springframework.beans.BeansException
import org.springframework.context.ApplicationContext
import org.springframework.context.ApplicationContextAware

import javax.sql.DataSource

@Slf4j
class ThirdGroovyClass implements ApplicationContextAware {
    Sql sql

    void logSomeInfo() {
        // sql been initialized
        log.debug "sql: ${sql}"
    }

    @Override
    void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        DataSource dataSource = applicationContext.getBean('dataSource', DataSource)
        sql = new Sql(dataSource)
    }
}
// grails-app/controllers/ascudemo/DemoController.groovy
package ascudemo

class DemoController {

    SomeService someService

    def index() {
        someService.logSomeInfo()
        render 'Success'
    }
}
// grails-app/services/ascudemo/SomeService.groovy
package ascudemo

import ascudemo.helpers.FirstGroovyClass
import ascudemo.helpers.SecondGroovyClass
import ascudemo.helpers.ThirdGroovyClass

class SomeService {

    FirstGroovyClass firstGroovyBean
    SecondGroovyClass secondGroovyBean
    ThirdGroovyClass thirdGroovyBean

    def logSomeInfo() {
        firstGroovyBean.logSomeInfo()
        secondGroovyBean.logSomeInfo()
        thirdGroovyBean.logSomeInfo()
    }
}
// grails-app/conf/spring/resources.groovy
import ascudemo.helpers.FirstGroovyClass
import ascudemo.helpers.SecondGroovyClass
import ascudemo.helpers.ThirdGroovyClass

beans = {
    // demonstrates one approach
    firstGroovyBean(FirstGroovyClass) { bean ->
        bean.autowire = 'byName'
    }

    // demonstrates another approach
    secondGroovyBean(SecondGroovyClass) { bean ->
        bean.autowire = 'byName'
    }

    // demonstrates a third approach
    thirdGroovyBean ThirdGroovyClass
}