Reputation: 21172
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
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