I need you to advice me with this issue, in a spring boot application I load some properties from database like (cron periods, email data), I need to export these properties
I think it’s a good idea to use BeanPostProcessor and Binder so that you don’t need to list all the attributes you want to read. The following code refers to ConfigurationPropertiesBindingPostProcessor.
public class PropertiesInsideDatabaseInitializer implements BeanPostProcessor, InitializingBean, ApplicationContextAware {
private JdbcTemplate jdbcTemplate;
private ApplicationContext applicationContext;
private BeanDefinitionRegistry registry;
private Map systemConfigMap = new HashMap<>();
private final String propertySourceName = "propertiesInsideDatabase";
public PropertiesInsideDatabaseInitializer(JdbcTemplate jdbcTemplate){
this.jdbcTemplate = jdbcTemplate;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
bind(ConfigurationPropertiesBean.get(this.applicationContext, bean, beanName));
return bean;
}
private void bind(ConfigurationPropertiesBean propertiesBean) {
if (propertiesBean == null || hasBoundValueObject(propertiesBean.getName())) {
return;
}
Assert.state(propertiesBean.getBindMethod() == ConfigurationPropertiesBean.BindMethod.JAVA_BEAN, "Cannot bind @ConfigurationProperties for bean '"
+ propertiesBean.getName() + "'. Ensure that @ConstructorBinding has not been applied to regular bean");
try {
Bindable> target = propertiesBean.asBindTarget();
ConfigurationProperties annotation = propertiesBean.getAnnotation();
BindHandler bindHandler = new IgnoreTopLevelConverterNotFoundBindHandler();
MutablePropertySources mutablePropertySources = new MutablePropertySources();
mutablePropertySources.addLast(new MapPropertySource(propertySourceName, systemConfigMap));
Binder binder = new Binder(ConfigurationPropertySources.from(mutablePropertySources), new PropertySourcesPlaceholdersResolver(mutablePropertySources),
ApplicationConversionService.getSharedInstance(), getPropertyEditorInitializer(), null);
binder.bind(annotation.prefix(), target, bindHandler);
}
catch (Exception ex) {
throw new BeanCreationException("", ex);
}
}
private Consumer getPropertyEditorInitializer() {
if (this.applicationContext instanceof ConfigurableApplicationContext) {
return ((ConfigurableApplicationContext) this.applicationContext).getBeanFactory()::copyRegisteredEditorsTo;
}
return null;
}
private boolean hasBoundValueObject(String beanName) {
return this.registry.containsBeanDefinition(beanName) && this.registry
.getBeanDefinition(beanName).getClass().getName().contains("ConfigurationPropertiesValueObjectBeanDefinition");
}
@Override
public void afterPropertiesSet() {
String sql = "SELECT key, value from system_config";
List
Modifying the PropertySources in Environment can also be achieved. The BeanPostProcessor interface is implemented to initialize it before creating the Bean
public class PropertiesInsideDatabaseInitializer implements BeanPostProcessor, InitializingBean, EnvironmentAware {
private JdbcTemplate jdbcTemplate;
private ConfigurableEnvironment environment;
private final String propertySourceName = "propertiesInsideDatabase";
public PropertiesInsideDatabaseInitializer(JdbcTemplate jdbcTemplate){
this.jdbcTemplate = jdbcTemplate;
}
@Override
public void afterPropertiesSet() {
if(environment != null){
Map systemConfigMap = new HashMap<>();
String sql = "SELECT key, value from system_config";
List