1

我正在尝试在 spring-mvc 控制器类上使用 Groovy mixin 转换,但 Spring 不会从混合类中获取请求映射。

class Reporter {
    @RequestMapping("report")
    public String doReport() {
        "report"
    }
}

@Mixin(Reporter)
@Controller
@RequestMapping("/a")
class AController {
    @RequestMapping("b")
    public String doB() {
        "b"
    }
}

当此代码运行时,.../a/burl 被映射并工作,.../a/report但未映射并返回 HTTP 404。在调试模式下,我可以通过鸭子类型访问doReport方法。AController

这种类型的请求映射继承在使用时实际上适用于 Java 类extends;那么为什么它不适用于 Groovy 的mixin呢?我猜要么是mixin转换不传输方法上的注释,要么是spring的组件扫描器在处理mixin之前工作。无论哪种方式,是否有一种更规范的方式来实现此功能(我不希望 AController 出于其他原因扩展 Reporter,所以这不是一个选项)?

4

2 回答 2

3

您可以在下面的 Groovy 用户邮件列表中找到我从Guillaume Laforge(Groovy 项目经理)那里得到的回复。

你好,

我没有看过 Spring MVC 的实现,但我怀疑它使用反射来查找可用的方法。并且“mixin”动态添加方法,它不是通过反射可见的东西。

多年来,@Mixin 一直存在问题,尽管我们努力修复它,但它的实现远非理想且漏洞百出。很可能我们很快就会弃用它,并引入诸如静态混合或特征之类的东西,然后它们会在类中“真正”添加方法,这意味着像 doReport() 这样的方法将被 Spring MVC 等框架看到.

该领域已经有一些举措,例如 Cédric 的原型分支以及 Grails 中的某些东西,基本上可以做到这一点(即通过 AST 转换添加“真实”方法)。尽管那里尚未做出明确的决定,但我们希望尽快进行调查并提供。

现在回到您的问题,也许您可​​以使用@Delegate 进行调查?您将在控制器类中添加一个 @Delegate Reporter 报告器属性。我不记得@Delegate 是否带有注释,我没有仔细检查过,但如果确实如此,那在短期内对您来说可能是一个很好的解决方案。

纪尧姆

使用 @Delegate 转换本身不起作用,所以我需要另一个建议。

再试一次……我记得我们说过为委托方法携带注释……实际上我们已经实现了。默认情况下它不启用,因此您必须使用 @Delegate 注释的参数激活它:http: //groovy.codehaus.org/gapi/groovy/lang/Delegate.html#methodAnnotations

你能试试@Delegate(methodAnnotations = true) 吗?

实际的解决方案是:

class Reporter {
    @RequestMapping("report")
    public String doReport() {
        "report"
    }
}

@Controller
@RequestMapping("/a")
class AController {
    @Delegate(methodAnnotations = true) private Reporter = new Reporter

    @RequestMapping("b")
    public String doB() {
        "b"
    }
}
于 2013-06-14T10:37:10.470 回答
0

当你使用注解映射请求时,一旦容器启动,它会扫描类路径,查找注解的类和方法,并在内部构建映射,而不是手动编写部署描述符。

扫描器从编译的 .class 文件中读取方法和注释。也许 Groovy mixin 的实现方式是在运行时解析它们,因此扫描器软件无法在编译的字节码中找到它们。

为了解决这个问题,你必须想办法在编译时静态地混入代码,这样带注解的方法才能真正写入到类文件中。

于 2013-06-14T08:03:42.197 回答