作为Spring @Value()的默认值的异常

时间:2018-07-11 15:02:55

标签: java spring spring-aop spring-annotations

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

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

enter image description here

5 个答案:

答案 0 :(得分:5)

默认情况下,

@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");
            }
        }

答案 1 :(得分:1)

恐怕您仅使用@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);
}

答案 2 :(得分:1)

要使属性替换正常进行,您需要像这样(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}")

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

答案 3 :(得分:0)

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

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

答案 4 :(得分:0)

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

  

如果未设置该属性,spring将会出现异常,并且您做对了。