【问题标题】:Exception as default value of Spring @Value()异常作为 Spring @Value() 的默认值
【发布时间】:2018-07-11 15:02:54
【问题描述】:

我是 Java/Spring 的新手。我需要从配置中读取一些值,但如果它不存在,它应该会失败。现在我有以下代码:

public class SomeClass {

    @Value("${some.property:#{null}}")
    private String someProperty;

    public void someMethod() throws Exception {
        if (someProperty == null) throw new AopConfigException("The property must be set");
    }

}

它工作正常,但我需要添加额外的 if 块。我可以写这样的东西吗?

@Value("${some.property:#{throw new AopConfigException(\"The property must be set\")}}")
private String someProperty;

@Value("${some.property:#{throwException()}}")
private String someProperty;

private static void throwException() {
    throw new AopConfigException("The property must be set");
}

立即失败

更新: 如果我不使用下面建议的一些默认值,那么它对我来说仍然不会失败。我没有java.lang.IllegalArgumentException

【问题讨论】:

  • 只使用@Value("${some.property}") 而不是@Value("${some.property:#{null}}")
  • spring 会查找该值,如果不存在则抛出异常
  • 它返回 "${some.property}" 而不是我的异常
  • 如果设置了属性,importDataPath 的值是多少?为了使属性替换起作用,您需要配置一个PropertyPlaceholderConfigurer bean。
  • @dpr ${import.data.path} 如截图所示

标签: java spring spring-aop spring-annotations


【解决方案1】:

@Value 默认是必需的。所以,只需使用

@Value("${some.property}")

而不是

@Value("${some.property:#{null}}")

因此,如果该属性不存在,您的应用程序将无法启动,并出现如下异常:

Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'invalid.value' in value "${invalid.value}"

更新:如果您想拥有一个可以像这样为空的密钥:

some.property=

如果该属性为空,您想抛出异常,则使用@PostConstruct,如下所示:

    @PostConstruct
    public void validateValue() {
        if (someProperty.isEmpty()) {
            throw new MyNiceException("error");
        }
    }

更多更新:如果您想在没有注册表项的情况下初始化 null

    @Value("${some.property:#{null}}")
    private String someProperty;

然后这样做:

        @PostConstruct
        public void validateValue() {
            if (someProperty == null) {
                throw new IllegalArgumentException("error");
            }
        }

【讨论】:

  • 它返回 "${some.property}" 而不是我的异常
  • Serg046,你可能是从 lombok 导入 @Value 吗?
  • 导入 org.springframework.beans.factory.annotation.Value;
  • 它应该会失败,并出现类似 Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'invalid.value' in value "${invalid.value}" 我刚刚在我的机器上所做的异常
【解决方案2】:

为了使属性替换起作用,您需要像这样 (example taken from here) 将 PropertySourcesPlaceholderConfigurer bean 添加到您的配置中:

@Bean
public static PropertySourcesPlaceholderConfigurer properties(){
  final PropertySourcesPlaceholderConfigurer pspc = new PropertySourcesPlaceholderConfigurer();
  // add your property files below
  final Resource[] resources = new ClassPathResource[]{new ClassPathResource("foo.properties")};
  pspc.setLocations( resources );
  // this will make the replacement fail, if property is not known
  pspc.setIgnoreUnresolvablePlaceholders(false); 
  return pspc;
}

如果您已经使用 @PropertySource 注释配置您的属性源,您应该能够省略手动将资源添加到 PropertySourcesPlaceholderConfigurer,因为它应该自动从 spring 环境中获取值。

一旦这个 bean 就位,只需使用

@Value("${data.import.path}")

没有默认值(正如其他答案中已经提到的),您的应用程序的初始化将在很早的阶段失败。

【讨论】:

  • 虽然这也可行,但它为所有引用值设置了所需的约束。在某些用例中可能会有所帮助。
  • 是的,当然。如果您不希望某些属性使用Exception,您只需在需要的地方提供默认值即可。
  • 所以解决方案是pspc.setIgnoreUnresolvablePlaceholders(false);?
  • 我认为默认是false。我只是添加它以使此设置明确。但是,是的,如果此设置为 false 并且您配置了 PropertySourcesPlaceholderConfigurer bean,它应该可以正常工作。请注意,PropertySourcesPlaceholderConfigurer 的 bean 方法是 static。这是正确连接此 bean 的必要条件。
  • @Serg046,还有?这解决了你的问题吗?您还有其他问题吗?
【解决方案3】:

恐怕您不能仅使用@Value 注释来做到这一点。但是,您可以通过使用 spring 环境读取值来检查是否设置了某个属性。如果未设置该值,则会抛出 IllegalStateException

因此,例如,如果您有环境变量,例如:

@Autowired
private ConfigurableEnvironment env;

然后就可以通过调用getRequiredProperty方法来初始化值了:

<T> T getRequiredProperty(java.lang.String key, java.lang.Class<T> targetType) 
      throws java.lang.IllegalStateException

因此,对于您的用例,您可以像这样初始化您的 bean:

@Bean
public SomeClass someClass () {

  String someProperty = env.getRequiredProperty ("some.property");

  return new SomeClass (someProperty);
}

【讨论】:

  • 谢谢,我知道这样。它需要可配置环境。然而,这是一个可行的解决方案,这就是我支持你的原因。但无论如何,这很有趣,为什么其他人说这是可能的,被否决但没有提供可行的解决方案 xD
【解决方案4】:

只需在 post 构造中进行验证,以确保它在 bean 创建后立即运行:

@PostConstruct
private static void throwException() {
  if (someProperty == null) {
    throw new AopConfigException("The property must be set");
  }
}

【讨论】:

  • 那我还需要进行两次条件检查。第一个用于null,第二个用于抛出异常。也许Spring 包含类似@RequiredValue() 而不是@Value()
  • @Serg046 @Value 默认需要的。
【解决方案5】:

请不要为您的属性提供默认值,例如 @Value("${some.property}")

如果没有设置属性,spring 将通过异常处理,你就做对了。

【讨论】:

  • 请看我更新问题中的截图
猜你喜欢
  • 2017-08-12
  • 1970-01-01
  • 1970-01-01
  • 2020-10-06
  • 2015-10-21
  • 1970-01-01
  • 1970-01-01
  • 2012-08-13
  • 2020-02-12
相关资源
最近更新 更多