Spring Boot SpEL和配置属性绑定到常量表达式

时间:2018-08-27 00:03:08

标签: java spring spring-boot spring-el compile-time-constant

使用Sprint Boot 2.0.4.RELEASE ,我具有以下属性类(简化了):

@Configuration
@EnableConfigurationProperties(MyOtherHierarchicalNonConstantProperties.class)
public class AppConfiguration {
    public static final String MY_CONSTANT = "${path.to.my-constant}";
}

application.yml(也简化了):

path.to.my-constant: mystring

问题

application.yml中的值永远不会分配给MY_CONSTANT,这是用作批注的参数所必需的。 (我希望在application.yml中设置构建环境之间的所有可配置选项!)MY_CONSTANT的值最终为${path.to.my-constant}

我整整一天都在处理这个问题,经过大量搜索后还尝试了几种不同的选择,例如:

  • ${${path.to.my-constant}}#1
  • #{${path.to.my-constant}}#2
  • ${#{path.to.my-constant}}
  • #{'${path.to.my-constant}'}
  • 还有更多...

其他(可能有帮助)信息

在某些情况下,我得到了与字符串值完全相同的表达式(如上所述),但在某些情况下,我得到了诸如以下的异常:

  • #1:IllegalArgumentException中的PropertyPlaceholderHelper.parseStringValueCould not resolve placeholder 'mystring' in value "${${path.to.my-constant}}"
  • #2:SpelEvaluationException中的PropertyOrFieldReference.readPropertyEL1008E: Property or field 'mystring' cannot be found on object of type 'org.springframework.beans.factory.config.BeanExpressionContext' - maybe not public or not valid?

这两者都表明,如果将初始表达式进一步包装在其他SpEL大括号内,则内部表达式将转换为所需的值。但是在那之后,它拒绝从外牙套中取出。 (很长一段时间以来,我一直在尝试数百次SpEL操作,以尝试以某种方式“提取”外部花括号的值...)

我还尝试过的一件事是,使用@ConfigurationProperties批注将常量移动到另一个属性类中,希望它会有所改变,但是结果似乎是相同的。

恳求

我知道有关在Spring Boot中为常量分配配置属性的问题已经问了很多,我来这里问了这个问题后,我还尝试了地球上的所有选项,但无可救药。< / p>

请大家一劳永逸地解决可配置常量表达式这一单一事实真相的可悲缺乏,并告诉我们如何以正确的方式做到这一点!(如果Spring Boot从来没有打算这样做,知道这些信息也可能会有所帮助...)

PS!请不要讨厌的骇客...

3 个答案:

答案 0 :(得分:0)

引用的字段属性既是静态的也是最终的注释。如果您使用的是Spring Boot注释(例如@ Value,@ Scheduled等);然后只需使用游戏。或者,如果您需要使用@Autowired,则将变量放入bean(或bean,您的喜好)中,然后将其自动装配到工厂服务中以创建对象。

但是看起来您正在使用@CrossOrigin,它似乎无法处理拼写,并且工厂不太适合此用例。因此,您需要像这样添加配置

@Configuration
public class CrossConfig{

    private String[] crossEndPoints = ...;

    @Bean
    public WebMvcConfigurer corsConfigurer(@Value("${path.to.my-constant}") String crossOrigin) {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                for(String endpoint : crossEndPoints){
                    registry.addMapping(endpoint).allowedOrigins(crossOrigin);
                }
            }
        };
    }
}

SpringDocs for CrossOrigins中所示。您只需要手动列出端点或以某种方式以编程方式找到它们即可。如果已经有了WebMvcConfigurer Bean,只需向其添加addCorsMappings(CorsRegistry)。

答案 1 :(得分:-1)

@anddero ...它将为您提供帮助...

@Configuration
@EnableConfigurationProperties(MyOtherHierarchicalNonConstantProperties.class)
public class AppConfiguration {
    public static final String MY_CONSTANT = "${path.to.my-constant}";

@Autowired
    public AppConfiguration (@Value("${path.to.my-constant}") String MY_CONSTANT ) {
        this.MY_CONSTANT = MY_CONSTANT ;
    }
}

答案 2 :(得分:-1)

我认为,对您来说这是最好的选择:

@Configuration
@EnableConfigurationProperties(prefix = "path.to")
public class AppConfiguration {
    public final String MY_CONSTANT;

    public UserService(@Value("${path.to.MY_CONSTANT}") String MY_CONSTANT) {
        this.MY_CONSTANT= MY_CONSTANT;
    }
}

您可以尝试一下并让我知道吗。