-3

I have an application (springboot 2) where customer would like to edit integer value, which represents value for maximum of AutoGrowCollectionLimit. This value is by default (according to spring docs) set to 256 and this is not enough for our purposes.

The code, where the property is set:

@InitBinder
public void initBinder(WebDataBinder binder) {
    binder.setAutoGrowCollectionLimit([configurable_number]);
}

This value should be configurable in configuration file (lets say some.txt), which will be delivered as a txt file next to an application. It doesn't matter now where will be some.txt file placed, even root for an application is ok for now.

This mean, that as a customer I am able to change it easy. Open some.txt file and change the value from i.e.: 256 to i.e.: 555.

During investigation I was able to find this. But its not suitable for my case. What I am searching for is configuration in some.txt file with really simple property i.e.:

AutoGrowCollectionLimit=[configurable_number]

According to spring docs, I tried following:

@InitBinder
public void initBinder(WebDataBinder binder) {
    binder.setAutoGrowCollectionLimit(${set.max.collectionLimit});
}

And also edited [projectUrl]/src/main/resources/application.yml with following:

set:
    max:
     collectionLimit: 500

IDE is expecting ')' or '}', when I am trying to call this property in:

binder.setAutoGrowCollectionLimit(${set.max.collectionLimit});

Can someone help?

Beginner
  • 207
  • 3
  • 6
  • 12
  • That is as far from a proper question as it gets. You should start by writing some code. – luk2302 Mar 01 '18 at 14:20
  • Ok, I edited the question, it is better right now? – Beginner Mar 01 '18 at 14:36
  • It's much better, yes. While you're waiting for the question to reopen, take a look at the [Spring Externalized Configuration](https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html) documentation, specifically the information around providing additional .yml or .properties files outside of your classpath. – Brian Mar 01 '18 at 17:51

1 Answers1

2

There are multiple ways to create externalized configurations in Spring Boot, but you need to use @Value injection to achieve pretty much all of them.

Value Injection

To inject your configuration values, you need to use the @Value annotation. This can be done in all the same places that you can use @Autowired. For example, on a property:

@Value("${com.example.app.host-name}")
private String hostName;

Or via a constructor or method:

@Value("${com.example.app.host-name}")
public void setHostName(String hostName) { ... }

Or on a specific constructor or method parameter:

public MyServiceBean(
        @Value("${com.example.app.host-name}") String hostName,
        @Value("${com.example.app.port}") int port) {
    ...
}

You can also supply defaults using this system using a : symbol, e.g.:

@Value("${com.example.app.port:8180}")
public void setPort(int port) { ... }

The ${} bit in all of these is interpreted using the Spring Expression Language. In this case, the ${property} syntax tells Spring to retrieve the value of property from the context, which is done by looking up the property in all the PropertySource beans in the context. You can do this yourself as well using Environment.getProperty via the context, e.g.:

ApplicationContext appCtx = ... ;
int port = appCtx.getEnvironment().getProperty("com.example.app.port", Integer.class);

It's just more convenient to use @Value annotations for the same reason it's more convenient to use @Autowired

Spring Boot Configuration

Since you're using Spring Boot, you already have some PropertySource instances in your app. For example, your application.yml file is loaded as a PropertySource. Note that Spring will translate a property named a.b.c to nested documents in your YAML file. In your case, this would be set.max.collectionLimit.

Spring Boot does this by looking for application.yml and application.properties files, as well as other sources of properties like System.getProperties(), and the default order for how Spring Boot looks for these properties can be found here in the documentation.

External Configuration

To externalize your configuration, you state that you don't want to use .yml files, but what about .properties? E.g.:

set.max.collectionLimit=555

You would place this file alongside your .jar file and name it application.properties. Any values in this file would override the values you have in your internal application.yml file.

They could also override it directly on the command line, e.g.:

java -jar your-app.jar --set.max.collectionLimit=555

Or via System properties:

java -Dset.max.collectionLimit=555 -jar your-app.jar

All of these would be valid ways of overriding the value, but only if you use value injection, e.g. via @Value.

Brian
  • 17,079
  • 6
  • 43
  • 66