簡體   English   中英

如何在抽象類方法中訪問注入的 Grails bean?

[英]How can I access injected Grails beans in an abstract class method?

我有一個抽象類,它實現了大量注冊為 bean 的具體類所繼承的大部分功能。 這些 bean 是通過自動裝配定義的。 例如:

abstract class MyAbstract {

    MyService myService
    MyBean myBean

    def doSomething() {
        def value = myService.something(myBean)
    }
}


class MyConcrete extends MyAbstract {
    def concreteField

    def doSomethingElse() {
         def value = myService.somethingElse(myBean)
    }
}

conf/spring/resources.groovy:

myConcrete(MyConcrete) { bean ->
    bean.autowire = true
    myBean = ref(MySpecificBeanImpl)
}

我的問題:

當我在 MyConcrete 實例中運行 doSomethingElse 方法時,一切都按預期工作,並且 myService 和 myBean 值由 DI 填充了正確的值。 當我在 MyConcrete 實例中執行 doSomething 方法時,myService 和 myBean 值都為空。 DI 值似乎在子類繼承的抽象方法中不可見。 這真的很糟糕。

我可以使用方法中的上下文持有者手動訪問值,或者我可以使用接受這些值作為參數的修改方法簽名將值從子類傳遞到抽象父類,但這些都不是好的解決方案。 它完全破壞了抽象類實現的用處,並且需要大量我不想維護的重復代碼。

更糟糕的是,在我的特定情況下,每個具體類的 myBean 的值實際上是不同的,在 resources.groovy 文件中顯式連接,因此通用持有者方法不起作用。

我已經瀏覽了許多與此相關的帖子,包括抽象類中的 Grails 服務,但並沒有弄清楚發生了什么。 抽象 bean 定義似乎是關於抽象 bean 定義屬性,與抽象類和子類繼承沒有任何關系。

(1) 這是 Grails/Spring DI 支持的限制嗎? (2) 抽象類還有什么我需要做的嗎?

您遺漏了一些細節,我不得不做出一些假設,但我創建了一個與您所描述的內容類似的應用程序。 https://github.com/jeffbrown/abstractbeanmethods 上的項目包含以下內容並且似乎有效:

src/groovy/demo/MyAbstract.groovy 包演示

abstract class MyAbstract {

    MyService myService
    MyBean myBean

    def doSomething() {
        myService.something(myBean)
    }
}

src/groovy/demo/MyConcrete.groovy

package demo

class MyConcrete extends MyAbstract {
    def doSomethingElse() {
         def value = myService.somethingElse(myBean)
    }
}

grails-app/conf/spring/resources.groovy

// Place your Spring DSL code here
beans = {
    myBeanImpl demo.MySpecificBeanImpl

    myConcrete(demo.MyConcrete) { bean ->
        bean.autowire = true
        myBean = ref('myBeanImpl')
    }
}

src/groovy/demo/MySpecificBeanImpl.groovy 包演示

class MySpecificBeanImpl implements MyBean {
}

src/groovy/demo/MyBean.groovy

package demo

interface MyBean {}

grails-app/service/demo/MyService.groovy 包演示

class MyService {

    def something(MyBean bean) {
        "Bean class name is ${bean.class.name} in MyService.something() method"
    }
    def somethingElse(MyBean bean) {
        "Bean class name is ${bean.class.name} in MyService.somethingElse() method"
    }
}

grails-app/controllers/demo/DemoController.groovy 包演示

class DemoController {
    def myConcrete
    def index() {
        def sb = new StringBuffer()
        sb << myConcrete.doSomething()
        sb << " and "
        sb << myConcrete.doSomethingElse()
        render sb
    }
}

您可能會發現那里的某事與您正在做的某事之間存在顯着差異。 如果您可以在該示例應用程序中隔離有問題的場景,或者提供可運行的代碼版本,那么我很樂意為您解決問題。

我使用@Autowired注釋解決了這個問題

import grails.gorm.services.Service
import org.springframework.beans.factory.annotation.Autowired

@Service(User)
abstract class UserService {

    @Autowired
    OrganizationService organizationService

    //...
}

在 Grails 3.3.5 上測試

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM