gpt4 book ai didi

java - Groovy 中的 Spring MVC 注释 Controller

转载 作者:搜寻专家 更新时间:2023-10-31 19:35:00 30 4
gpt4 key购买 nike

我在 src/main/groovy/... 中有这个

package com.mycompany.web;
// imports....

@Controller
class GroovyController {

@RequestMapping("/status_groovy")
public @ResponseBody String getStatus() {
return "Hello World from groovy!";
}
}

使用 maven 3 和 spring 3.1(里程碑)。 Spring MVC 非常适合 java Controller ,一切都设置得很好。 groovy 类编译良好,可以在 classes 目录中与 java Controller 类一起找到。

我在同一个包中用 java (JavaController) 编写了类似的 Controller ,但在 src/main/java 下,它被 spring 正确拾取并映射,当我点击 url 时,我可以在屏幕上看到响应。

package com.mycompany.web;
// imports....

@Controller
class JavaController {

@RequestMapping("/status")
public @ResponseBody String getStatus() {
return "Hello World!";
}
}

Jetty 正常启动,日志中没有错误,但在日志中我没有看到 groovy url 被映射,而我可以看到 java url。

2011-09-23 16:05:50,412 [main] INFO  org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/status],methods=[],params=[],headers=[],consumes=[],produces=[]}" onto public java.lang.String com.mycompany.web.JavaController.getStatus()

所有设置都很好,因为应用程序的其他部分可以很好地处理注释(组件扫描等),只是我无法在 GroovyController

中获取映射的 url

谁能解释需要做什么才能让用 groovy 编写的 Controller 正常工作?

PS:我避免使用 GroovyServlet 来运行脚本,因为它在 bean 注入(inject)和 url 路径映射方面有很大的缺点。

最佳答案

恕我直言 Ben(我的同事),这里的问题不在于 Spring 正在创建 cglib 代理。相反,它正在创建一个动态的 JDK(或基于接口(interface)的)代理。这种创建代理的方法只能实现在目标实现的接口(interface)中声明的方法。实际上,您希望 Spring 创建一个 cglib 代理,它创建一个作为目标对象子类的代理,因此可以重新创建其所有公共(public)方法。除非您另有说明,否则如果目标对象未实现任何接口(interface),Spring 将创建一个 cglib 代理,否则将创建一个基于接口(interface)的代理。由于所有 Groovy 对象都实现了 GroovyObject,因此您将获得一个基于接口(interface)的代理,即使您没有在 Groovy Controller 中显式实现任何接口(interface)。 Ben 的解决方案是正确的,因为如果您使用所有 Controller 方法创建一个接口(interface),您将获得预期的行为。另一种方法是创建一个 BeanFactoryPostProcessor,它指示 Spring 为实现 GroovyObject 且仅实现 GroovyObject 的类创建 cglib 代理。这是代码:

/**
* Finds all objects in the bean factory that implement GroovyObject and only GroovyObject, and sets the
* AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE value to true. This will, in the case when a proxy
* is necessary, force the creation of a CGLIB subclass proxy, rather than a dynamic JDK proxy, which
* would create a useless proxy that only implements the methods of GroovyObject.
*
* @author caleb
*/
public class GroovyObjectTargetClassPreservingBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
private static final Logger logger = LoggerFactory.getLogger(GroovyObjectTargetClassPreservingBeanFactoryPostProcessor.class);

@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
for (String beanDefName : beanFactory.getBeanDefinitionNames()) {
BeanDefinition bd = beanFactory.getBeanDefinition(beanDefName);
//ignore abstract definitions (parent beans)
if (bd.isAbstract())
continue;
String className = bd.getBeanClassName();
//ignore definitions with null class names
if (className == null)
continue;
Class<?> beanClass;
try {
beanClass = ClassUtils.forName(className, beanFactory.getBeanClassLoader());
}
catch (ClassNotFoundException e) {
throw new CannotLoadBeanClassException(bd.getResourceDescription(), beanDefName, bd.getBeanClassName(), e);
}
catch (LinkageError e) {
throw new CannotLoadBeanClassException(bd.getResourceDescription(), beanDefName, bd.getBeanClassName(), e);
}

Class<?>[] interfaces = beanClass.getInterfaces();
if (interfaces.length == 1 && interfaces[0] == GroovyObject.class) {
logger.debug("Setting attribute {} to true for bean {}", AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, beanDefName);
bd.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, true);
}
}
}
}

只需在您的上下文中包含一个这种类型的 bean,瞧!您可以拥有 Groovy Controller 而无需定义接口(interface)。

关于java - Groovy 中的 Spring MVC 注释 Controller ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7534529/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com