title: Can multiple property names be specified in Spring's @Value annotation?
body: <p>I'm already familiar with the base behavior of Spring's <code>@Value</code> annotation to set a field to the value of a project property like so:</p>
  
  <p><strong>Project's Property File</strong></p>
  
  <pre><code>foo.bar=value
  </code></pre>
  
  <p><strong>Project's Configuration Class</strong></p>
  
  <pre><code>@Configuration
  public class MyConfig {
      @Value("${foo.bar}")
      private String myValue;
  }
  </code></pre>
  
  <p>However I'm trying to make a SpringBoot starter project with conditional configuration and would like to standardize the property names to something useful such as "com.mycompany.propertygroup.propertyname", but to ease transition and encourage adoption, I want to support the old property names for a time as well, and was thus wondering if there was some way to allow multiple property names to set the same field? For instance:</p>
  
  <p><strong>My Theoretical Starter's Config</strong></p>
  
  <pre><code>@Configuration
  public class MyConfig {
      @Value("${com.mycompany.propertygroup.propertyname}" || "${oldconvention.property}")
      private String myValue;
  }
  </code></pre>
  
  <p><strong>Project A's Property</strong></p>
  
  <pre><code>oldconvention.property=value
  </code></pre>
  
  <p><strong>Project B's Property</strong></p>
  
  <pre><code>com.mycompany.propertygroup.propertyname=value
  </code></pre>
  
  <p>I can't seem to find any documentation or SO answers on whether or not this is possible and how to achieve it if so... So I'm wondering if it is possible, or if it's not, is there an alternative to the <code>@Value</code> annotation that can be used to achieve the same effect?</p>
  
  <p><strong>Edit to Clarify:</strong>
  I would not want to keep track of multiple values so I do not need instruction on how to get multiple values... the objective is to consolidate into a <strong>SINGLE VALUE</strong> that which may have multiple names. In practice, it would only ever have one name-value per project that uses the starter... only in rare cases when someone perhaps forgot to delete the old property would each property name be used (and it would probably have the same value anyway). In such cases, the NEW CONVENTION NAME-VALUE WOULD BE THE <strong>ONLY</strong> ONE USED.</p>
  
  <h2>Update</h2>
  
  <p>While the SpEL expression answers provided works when both properties are present, the application context cannot load when only one of the property names is present. Example:</p>
  
  <p><strong>Updated Configuration Class</strong></p>
  
  <pre><code>@Value("#{'${com.mycompany.propertygroup.propertyname}' != null ? '${com.mycompany.propertygroup.propertyname}' : '${oldconvention.propertyname}'}"
  private String myProperty;
  </code></pre>
  
  <p><strong>Updated Property File</strong></p>
  
  <pre><code>com.mycompany.propertygroup.propertyname=somevalue
  </code></pre>
  
  <p><strong>Error</strong></p>
  
  <pre><code>Caused by: java.lang.IllegalArgumentException: 
  Could not resolve placeholder 'oldconvention.propertyname' in value
  "#{'${com.mycompany.propertygroup.propertyname}' != null ? '${com.mycompany.propertygroup.propertyname}' : '${oldconvention.propertyname}'}"
  </code></pre>
  
  <p>Requiring both property names to be present defeats the purpose, which is to allow an implementing project to configure this starter using EITHER the old convention OR the new convention...</p>
  
  <p><strong>Another Update...</strong></p>
  
  <p>I've been playing around with the SpEL expression a bit, and I've got the conditional check working when the property is present and when it's not, but I'm having trouble with property resolution after the fact. I think the problem is because property defaults and complex SpEL expressions don't play nice together.</p>
  
  <pre><code>@Value("#{${com.mycompany.propertygroup.propertyname:null} != null ? '${com.mycompany.propertygroup.propertyname}' : '${oldconvention.propertyname}'}")
  private String myProperty;
  </code></pre>
  
  <p>When my SpEL is written like the above, I get a cannot resolve property placeholder exception, meaning that both properties have to be present in order for the SpEL expression to evaluate. So I got to thinking, I could use the default property syntax that I've seen for resolving optional properties: <code>@Value("${myoptionalproperty:defaultValue}")</code></p>
  
  <p>So below is my attempt to combine the default property resolution with the SpEL expression:</p>
  
  <pre><code>@Value("#{${com.mycompany.propertygroup.propertyname:null} != null ? '${com.mycompany.propertygroup.propertyname:}' : '${oldconvention.propertyname:}'}")
  private String myProperty;
  </code></pre>
  
  <p>When using the default property notation, I keep getting this error:</p>
  
  <pre><code>org.springframework.expression.spel.SpelParseException: 
  EL1041E: After parsing a valid expression, there is still more data in the expression: 'colon(:)'
  </code></pre>
  
  <p>and when I Googled that error, the popular answer was that properties had to be wrapped in single quotes so that they evaluate to a string... but they're already wrapped (except the first one.. I had to unwrap that one since I wanted that to evaluate to a literal null for the null check). So I'm thinking that defaults can't be used with properties when they're wrapped in a spell expression. In truth, I've only ever seen the default property set when a <code>@Value</code> annotation is set with just a pure property holder, and all properties I've seen used in a SpEL expression never had a default set.</p>