我们可以在其他注释中使用spring表达式(spel)吗?

时间:2010-07-19 14:28:16

标签: java spring

我希望能够做到这一点:

@Controller
@RequestMapping("/#{handlerMappingPaths.security}/*")
public class SecurityController {
  etc

  //for instance, to resuse the value as a base for the folder resolution     
  @Value("#{handlerMappingPaths.security}/")
  public String RESOURCE_FOLDER;

  @RequestMapping(value="/signin-again", method = RequestMethod.GET)
    public String signinAgainHandler() {
        return RESOURCE_FOLDER + "signin_again";
    }
}

现在似乎没有用,我错过了什么吗?

3 个答案:

答案 0 :(得分:2)

你可以找到这样的事情的一种方法是自己看看。这是eclipse的一个例子,但它应该与其他IDE类似:

首先,确保您拥有正在使用的弹簧库的来源。如果您使用maven,using the maven-eclipse-plugin或使用m2eclipse,这是最简单的。

然后,在Eclipse中选择Navigate -> Open Type...。输入您要查找的类型(类似RequestMa*应该为像我这样的惰性打字机执行此操作)。输入/ OK。现在,右键单击源文件中的类名,然后选择References -> Project。在搜索视图中,将显示此类或注释的所有用法。

其中一个是DefaultAnnotationHandlerMapping.determineUrlsForHandlerMethods(Class, boolean),此代码段会告诉您未评估表达式语言:

ReflectionUtils.doWithMethods(currentHandlerType, new ReflectionUtils.MethodCallback() {
    public void doWith(Method method) {
        RequestMapping mapping = AnnotationUtils.findAnnotation(
                                     method, RequestMapping.class);
        if (mapping != null) {
            String[] mappedPatterns = mapping.value();
            if (mappedPatterns.length > 0) {
                for (String mappedPattern : mappedPatterns) {
                    // this is where Expression Language would be parsed
                    // but it isn't, as you can see
                    if (!hasTypeLevelMapping && !mappedPattern.startsWith("/")) {
                        mappedPattern = "/" + mappedPattern;
                    }
                    addUrlsForPath(urls, mappedPattern);
                }
            }
            else if (hasTypeLevelMapping) {
                urls.add(null);
            }
        }
    }
}, ReflectionUtils.USER_DECLARED_METHODS);

请记住,它被称为开源。如果你不试图理解你正在使用的是什么,那么使用开源软件毫无意义。

答案 1 :(得分:2)

答案在2020年:对于当前的Spring版本,可以在@RquestMappning批注中使用SpEL表达式。 它们已正确解析。

内部详细信息:
Spring的RequestMappingHandlerMapping调用embeddedValueResolver#resolveStringValue.
EmbeddedValueResolver的JavaDoc声明以下内容:

StringValueResolver适配器,用于解析占位符和表达式 针对ConfigurableBeanFactory。请注意,此适配器可以解析 表达式,与 ConfigurableBeanFactory.resolveEmbeddedValue方法。的 使用的BeanExpressionContext用于普通的bean工厂,没有 为任何要访问的上下文对象指定的范围。

因为:4.3

这意味着将同时解析常规占位符(例如${my.property})和SpEL表达式。

请注意,因为先解析常规占位符,然后再解析SpEL表达式,所以甚至可以将属性的值设置为SpEL表达式。 Spring首先将占位符替换为属性值(SpEL表达式),然后解析SpEL表达式。

答案 2 :(得分:0)

@Sean回答了spring是否支持这一问题,但我也想回答一般问题,即在使用注释时如何不复制配置。事实证明,这可以使用静态导入,如:

import static com.test.util.RequestMappingConstants.SECURITY_CONTROLLER_PATH

@Controller
@RequestMapping("/" + SECURITY_CONTROLLER_PATH + "/*")
public class SecurityController {
  etc

  //for instance, to resuse the value as a base for the folder resolution     
  public String RESOURCE_FOLDER = SECURITY_CONTROLLER_PATH + "/";

  @RequestMapping(value="/signin-again", method = RequestMethod.GET)
    public String signinAgainHandler() {
        return RESOURCE_FOLDER + "signin_again";
    }
}