10

I'm looking to centralize access to all of my property values so that I can do things like make sure everything uses the same name for properties, the same default values, etc. I've created a class to centralize all of this, but I'm not sure how the classes that need access to these values should get them, since you can't autowire Strings.

My class is something like this:

@Configuration
public class SpringConfig {
    @Autowired
    @Value("${identifier:asdf1234}")
    public String identifier;
}

Where I might use it in multiple classes

public class Foo {
    @Autowired 
    private String theIdentifier;
}

public class Bar {
    @Autowired 
    private String anIdentifier;
}
css
  • 944
  • 1
  • 9
  • 27
  • Are you saying there's a property value you'd like to inject in multiple beans and therefore want all `@Value` values to be referring to the same property name? – Sotirios Delimanolis Aug 20 '14 at 17:38
  • Yes. I've updated with an example to try and explain it a little better. – css Aug 20 '14 at 18:16

3 Answers3

19

Initialized a String bean based on the property:

@Configuration
public class SpringConfig {

    @Bean
    public String identifier(@Value("${identifier:asdf1234}") identifier) {
       return identifier;
    }
}

Then inject it by bean name using Spring's SpEL beanName expression "#{beanName} in a @Value annotation

@Component
public class Foo {
    @Value("#{identifier}")
    private String oneIdentifier;
}

public class Bar {
   @Value("#{identifier}")
   private String sameIdentifier;
}
Ricardo Veguilla
  • 3,107
  • 1
  • 18
  • 17
8

Another solution would be to create a Spring bean with all your configuration and autowire it:

@Component
public class MyConfig {
    @Value("${identifier:asdf1234}")
    public String identifier;

    public String getIdentifier() {
        return identifier;
    }
}

And in your other classes:

public class Foo {
    @Autowired
    private MyConfig myConfig;

    public void someMethod() {
        doSomething(myConfig.getIdentifier());
    }
}
Christophe L
  • 13,725
  • 6
  • 33
  • 33
1

There's no clean solution to this, in my opinion. The simplest I can think of is to use a static constant String field that holds the property placeholder.

public final class Constants {
    private Constants() {}
    public static final String PROPERTY_NAME= "${identifier.12345}";
}

and have all @Value annotations use it

public class Foo {
    @Value(Constants.PROPERTY_NAME)
    private String theIdentifier;
}

public class Bar {
    @Value(Constants.PROPERTY_NAME)
    private String anIdentifier;
}

Now, if you ever need to change the property name, you only need to change it in Constants. But make sure to recompile everything.

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724