我有一个抽象类,它实现了大量注册为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)
}
}
Run Code Online (Sandbox Code Playgroud)
CONF /弹簧/ resources.groovy:
myConcrete(MyConcrete) { bean ->
bean.autowire = true
myBean = ref(MySpecificBeanImpl)
}
Run Code Online (Sandbox Code Playgroud)
我的问题:
当我在MyConcrete实例中运行方法doSomethingElse时,一切都按预期工作,并且通过DI用适当的值填充myService和myBean值.当我在MyConcrete实例中执行doSomething方法时,myService和myBean值都为null.似乎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)
}
}
Run Code Online (Sandbox Code Playgroud)
SRC /常规/演示/ MyConcrete.groovy
package demo
class MyConcrete extends MyAbstract {
def doSomethingElse() {
def value = myService.somethingElse(myBean)
}
}
Run Code Online (Sandbox Code Playgroud)
的grails-app/CONF /弹簧/ resources.groovy
// Place your Spring DSL code here
beans = {
myBeanImpl demo.MySpecificBeanImpl
myConcrete(demo.MyConcrete) { bean ->
bean.autowire = true
myBean = ref('myBeanImpl')
}
}
Run Code Online (Sandbox Code Playgroud)
src/groovy/demo/MySpecificBeanImpl.groovy包演示
class MySpecificBeanImpl implements MyBean {
}
Run Code Online (Sandbox Code Playgroud)
SRC /常规/演示/ MyBean.groovy
package demo
interface MyBean {}
Run Code Online (Sandbox Code Playgroud)
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"
}
}
Run Code Online (Sandbox Code Playgroud)
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
}
}
Run Code Online (Sandbox Code Playgroud)
您可能会发现某些内容与您正在做的某些内容之间存在显着差异.如果您可以在该示例应用程序中隔离出有问题的场景,或者提供代码的可运行版本,那么我将很乐意为您解决问题.
| 归档时间: |
|
| 查看次数: |
1374 次 |
| 最近记录: |