LppEdd
LppEdd

Reputation: 21172

Spring context initialization with runtime values

I'm trying to integrate Spring in a standalone Swing application.
The Swing application asks for login details at start-up, which should then be used to create a singleton DataSource Bean.

However I can't come up with a way to pass those login info (as Java object) to the Spring ApplicationContext during initialization (which would then be passed down to the @Bean producer method).

Any ideas?


Possible solution:

@SpringBootApplication
public class DemoSwingApplication {
  public static void main(final String[] args) {
    ...

    final var loginInfo = buildLoginInfo();

    try (final var context = new AnnotationConfigApplicationContext()) {
      context.getBeanFactory().registerSingleton("loginInfo", loginInfo);
      context.register(DemoSwingApplication.class);
      context.refresh();
    }
  }
}

Upvotes: 0

Views: 420

Answers (1)

Sachin Gorade
Sachin Gorade

Reputation: 1467

There are multiple ways in which you can do this,

Using BeanDefinitionRegistryPostProcessor - Create a bean which will implement BeanDefinitionRegistryPostProcessor and then store the BeanDefinitionRegistry instance and dynamically register your bean.

@Component
public class DbConfigurer implements BeanDefinitionRegistryPostProcessor, BeanFactoryAware {

    private BeanDefinitionRegistry beanDefinitionRegistry;

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
        this.beanDefinitionRegistry = beanDefinitionRegistry;
    }

    public void registerDataSourceBean() {
        beanDefinitionRegistry.registerBeanDefinition("dataSource", new RootBeanDefinition(DataSource.class,
                BeanDefinition.SCOPE_SINGLETON, yourDataSourceBeanSupplier));
    }
}

Using BeanFactoryAware - This is similar to implementation that you provided but by implementing BeanFactoryAware interface but downside of this is to check for BeanFactory instance -

@Component
public class DbConfigurer implements BeanDefinitionRegistryPostProcessor, BeanFactoryAware {

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) beanFactory; // Need to cast
    }
}

And then in your UI component, inject this And and register bean when config properties are available -

@Component
public class MainWindow extends JFrame {

    private final DbConfigurer dbConfigurer;

    // register bean once user provides config properties
}

and start your application using headless mode disabled -

@SpringBootApplication
public class DesktopApplication {

    public static void main(String[] args) {
        new SpringApplicationBuilder(DesktopApplication.class).headless(false).run(args);
    }

}

Upvotes: 1

Related Questions