I am working on a project using Spring Data JPA (on Tomcat 7). I'am implementing a BeanFactoryPostProcessor to dynamically create my DataSources. But the problem is that my DataSource's information (name, url, etc..) is stored in a database itself.
@Component
class DatasourceRegisteringBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
// This doesn't work
@Autowired DatabaseService databaseService;
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// my code here ...
// ...
}
}
As you can see, i was trying to inject a service which can get me a list of all DataSources from my database, but it doesn't work. Is the anyway to connect to the database and get that list within the BeanFactoryPostProcessor class? Any other workaround will be welcome. :)
BeanFactoryPostProcessors are a very special kind of concept in Spring. They are components that operate onBeanDefinitioninstances, which are a metamodel of the bean instances to be created.That means, that at the point in time when the
BFPPs are invoked, no bean instances have been created yet as the metamodel is about to be post processed (as the name suggests). Hence beans depended on by theBFPPwill be initialized extremely early in the lifecycle of the container. Thus it's highly recommended to not depend on application components fromBFPPs or - if really required - only on beans that don't necessarily trigger the creation of a lot of downstream components.That said, you shouldn't depend on especially repositories from
BFPPs as they usually require the creation of a lot of infrastructure components. I'd recommend getting the configuration properties that are required to connect to the configuration database (JDBC URL, username, password, etc.) and just create a throw-awayDataSourcethat's only used to create a newBeanDefinitionfor a newDataSourcethat's going to be used by the application eventually.So here are the recommended steps (from the top of my head - might need some tweaking):
DataSource@PropertySourcepointing to the properties containing the coordinates to connectinject the values of that
PropertySourceinto the constructor of theBFPP: