RangerReturn
RangerReturn

Reputation: 171

@Value with SpEL not able to get values from properties

I have the following code in a sample Spring Boot Application

@Configuration
@PropertySource("classpath:second.properties")
public class PropertyConfig {

    @Value("#{guru.username}")
    String user;

    @Value("#{guru.password}")
    String password;

    @Value("#{guru.url}")
    String url;


    @Bean
    FakeDataSource getFakeDataSource() {
        FakeDataSource fk = new FakeDataSource();

        fk.setName(user);
        fk.setPassword(password);
        fk.setUrl(url);

        return fk;
    }

    @Bean
    PropertySourcesPlaceholderConfigurer getPropertySourcesPlaceholderConfigurer() {
        PropertySourcesPlaceholderConfigurer placeholderConfigurer= new PropertySourcesPlaceholderConfigurer();
        //placeholderConfigurer.setLocation(new ClassPathResource("second.properties"));

        return placeholderConfigurer;
    }
}

And FakeDataSource is a simple pojo with the name, passowrd, url properties.

Then my main application

@SpringBootApplication
public class SpringGuru101DependencyInjectionApplication {
    public static void main(String[] args) {
        ApplicationContext ctx = SpringApplication.run(SpringGuru101DependencyInjectionApplication.class, args);

        // Step 2: Make Class
        FakeDataSource fakeDataSource = ctx.getBean(FakeDataSource.class);

        System.out.println(fakeDataSource.getName());
    }
}

but the sout statement is printing null, my second.properties file is present in my resources directory with following content

guru.username=Saurabh
guru.password=ido
guru.url=http://example.com

Upvotes: 1

Views: 1859

Answers (2)

ankit_kurani
ankit_kurani

Reputation: 29

If you are using Spring-boot, you can use another method for reading configuration which is Spring boot recommended. This will help you get rid of all the @Value notations, allowing spring inject properties without additional hints.

You can potentially do something like:

@ConfigurationProperties("foo")
public class FooProperties {

private boolean enabled;

private InetAddress remoteAddress;

private final Security security = new Security();

public boolean isEnabled() { ... }

public void setEnabled(boolean enabled) { ... }

public InetAddress getRemoteAddress() { ... }

public void setRemoteAddress(InetAddress remoteAddress) { ... }

public Security getSecurity() { ... }

public static class Security {

    private String username;

    private String password;

    private List<String> roles = new ArrayList<>(Collections.singleton("USER"));

    public String getUsername() { ... }

    public void setUsername(String username) { ... }

    public String getPassword() { ... }

    public void setPassword(String password) { ... }

    public List<String> getRoles() { ... }

    public void setRoles(List<String> roles) { ... }

}

}

The POJO above defines the following properties:

foo.enabled, false by default foo.remote-address, with a type that can be coerced from String foo.security.username, with a nested "security" whose name is determined by the name of the property. In particular the return type is not used at all there and could have been SecurityProperties foo.security.password foo.security.roles, with a collection of String

More details: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html

Upvotes: 0

LHCHIN
LHCHIN

Reputation: 4009

There are two places should be corrected:
(1) As I said in the comment of your question, you should replace the wellhead sign (#) to dollar sign ($) for reading values from your configuration file. For example: @Value("${guru.username}").

(2) You missed public static in front of the method getPropertySourcesPlaceholderConfigurer.
And this modified method should be looked like as follows:

@Bean
public static PropertySourcesPlaceholderConfigurer getPropertySourcesPlaceholderConfigurer() {
    PropertySourcesPlaceholderConfigurer placeholderConfigurer= new PropertySourcesPlaceholderConfigurer();
    //placeholderConfigurer.setLocation(new ClassPathResource("second.properties"));

    return placeholderConfigurer;
}

Upvotes: 1

Related Questions