user10871691
user10871691

Reputation:

Spring bean with placeholder create a second bean with different profile

Suppose there is a Spring managed bean like this one:

@Component
@Profile("prod")
public class MyBean {

    @Value("${x.y.id:-1}")
    private int id;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
}

Also, the property x.y.id does exist in application-prod.properties file.

Now, if I want to use the same class to create another managed bean, with a different profile, in a configuration class like this:

@Profile("dev")
@Bean
public MyBean myBean() {
    MyBean myBean = new MyBean();
    myBean.setId(10);
    return myBean;
}

it doesn't work since id field would end up with -1 value because the placeholder's default value has the final word.

Question Is it possible to have a second managed bean in a situation like this?


Adding x.y.id=10 in application-dev.properties does work for the case above, but not on this one:

@Profile("dev")
@Bean
public MyBean myBean() {
    MyBean myBean = new MyBean();
    myBean.setId(10);
    return myBean;
}

@Profile("dev")
@Bean
public MyBean myAnotherBean() {
    MyBean myBean = new MyBean();
    myBean.setId(20);
    return myBean;
}

Upvotes: 0

Views: 223

Answers (2)

Mark Bramnik
Mark Bramnik

Reputation: 42441

I'm not sure what is "placeholder's default value has the final word..."

However I think the following should work:

You can rewrite MyBean class so that it won't use @Value and in general will use constructor injection:

public class MyBean {

    private final int id;

    public MyBean(int id) {this.id = id;}

    public int getId() {
        return id;
    }
}

In this case, the configuration can be defined as follows:

@Configuration
@Profile("prod") // also possible to be used per bean
public class MyProductionConfiguration {

    @Bean
    public MyBean myBean( @Value("${x.y.id:-1}") int id) {
       return new MyBean(id);
    }
}

@Configuration
@Profile("dev")
public class MyDevConfiguration {

    @Bean
    public MyBean myBean() {
       return new MyBean(10);
    }
}

Upvotes: 0

Marco Behler
Marco Behler

Reputation: 3724

To keep things homogenous, you might simply fallback to having an application-dev.properties file and set the property there.

Upvotes: 0

Related Questions