Question

What is the advantage of using @PropertySource in Spring?


Given a configuration ...

@Configuration
@PropertySource("classpath:foo.properties")
public class Config {}

... we can access an Environment

public class Foo {
      @Autowire Environment env;

      public void bar() {
         String foo = env.getProperty("foo");
      }
}

This we can already do with regular system properties already. Even profile-management is easy with system properties

if (profile1) System.setProperty("foo", "bar") 
else          System.setProperty("foo", "baz");

...and

System.getProperty("foo"); // also shorter than autowiring an environment

Plus system properties doesn't have some of the shortcomings of @PropertySource

  • System properties are iterable, PropertySource is not
  • PropertySource does not allow fallback properties - and creating a custom PropertySource at least equals the code of doing the same with system properties.
  • Environment and @Autowire increase Spring coupling
Était-ce utile?

La solution 2

Reading values from a property file is far superior to hard coding them in your class files. If you hard code then you need to recompile if you want to change any of them.

To answer your criticisms:

1.

System properties are iterable, PropertySource is not

Most PropertySources extend EnumerablePropertySource. Though I'm unsure of a use case where you would want to iterate over your properties

2.

PropertySource does not allow fallback properties - and creating a custom PropertySource at least equals the code of doing the same with system properties.

Rather than hide fall backs in a a custom property source you can just use the standard spring property getters. e.g.

env.getProperty("someProp", "someFallback")

or even

env.getProperty("someProp", env.getProperty("someFallback", "lastResort"))

3.

Environment and @Autowire increase Spring coupling

It's the auto-wiring that gives spring coupling, and you don't need to use it if you don't want to. e.g.

public class Foo {
    private final String foo;

    public Foo(String foo) {
        this.foo = foo;
    }

    public void bar() {
        // doo something with foo
    }
}

and

@Configuration
@PropertySource("classpath:foo.properties")
public class Config {
    @Autowired
    public Environment env;

    @Bean
    public Foo foo() {
        return new Foo(env.getProperty("foo"));
    }
}

Autres conseils

  1. You can give provide property file with key/value pairs and that will be injected into your environment. This makes it bit easier if you have a large number of environment properties. Also you can specify more than one file.
  2. The assumption is you would know the property beforehand(before using it). Hence a key value pair makes sense.
  3. You have spring active profile concept to manage profiles. It is much easier than doing via system properties yourself.
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top