When @EnableConfigurationProperties
is used, corresponding ConfigurationProperties
class is registered as a bean with name <prefix>-<fqcn>
.
This bean name is generated by ConfigurationPropertiesBeanRegistrar#getName
.
This auto-generated name is very inconvenient when the registered bean needs to be referenced by other places such as SpEL.
Current workaround to specify bean name is to use @ConfigurationProperties
with @Bean
instead of @EnableConfigurationProperties
.
@Bean
public MyProperties myProperties() {
return new MyProperties();
}
@ConfigurationProperties("my")
public class MyProperties {
}
If it is declared as a bean, ConfigurationPropertiesBindingPostProcessor
performs binding and the configuration properties bean exists with the bean name via @Bean
.(myProperties
in this example)
I would like to have a capability in @EnableConfigurationProperties
to specify bean name (or may be alias to <prefix>-<fqcn>
) for binding ConfigurationProperties beans.
For example:
@EnableConfigurationProperties(
value = {FooProperties.class, BarProperties.class},
beanNames = {"fooProps", "barProps"})
If this sounds ok, then I'll proceed to create a PR.
Thanks,
Comment From: bclozel
I'm not sure we want to go there. Configuration properties classes are public API by nature, but they're much more likely to change than the rest (because they tend to follow closely changes in 3rd party libraries). We're already considering updating our documentation to reflect that (see #19199), so I'm wondering if referencing properties beans by their name or using them in a SpEL expression is really advised.
Comment From: ttddyy
Hi, @bclozel
Just for FYI, my usage is to reference to our own properties. (not 3rd party)
Something like this:
my:
schedule:
delay: 30s
@Scheduled(
initialDelay = "#{@myProperties.getSchedule().getDelay().toMillis() + " +
"T(java.util.concurrent.ThreadLocalRandom).current().nextInt(3*60*1000)}")
Here, getDelay()
returns Duration
then call toMillis()
to get mili seconds.
Comment From: philwebb
We discussed this as a team today and we aren't convinced that using a second array in the @EnableConfigurationProperties
annotation is a good idea. In this case we'd recommend using @Component
on the bean or using an @Bean
method as you're already doing. You could also look at @Import
with a custom ImportBeanDefinitionRegistrar
and use that to register your beans.
One other thing to consider is not trying to use SpEL for this type of configuration. It can be quite brittle as it doesn't fail until runtime. I believe that Spring offers programmatic support for scheduling beans via the SchedulingConfigurer
interface which should allow you to move this logic into real code.
Comment From: ttddyy
ok, thanks @philwebb
I think it would be useful if there is some documentation about this as a guideline or best practice. So, that I can point other developers about it.
Something like "Referencing @ConfigurationProperties as a bean in SpEL"
- use @Component
or @Bean
to give simple beanname
- or write a custom ImportBeanDefinitionRegistrar
to register such beans
- alternatively, find programmatic way of filling such information
- etc.
Comment From: rehevkor5
Unfortunately, this tends to make people use cron
with a property expression, since it can use the string value directly. eg. @Scheduled(cron = "${something.cron}")
. But, it's more complicated to understand than fixedRateString
.
Related: https://github.com/spring-projects/spring-framework/issues/22013