2

我正在使用 Spring Data JPA(在 Tomcat 7 上)开发一个项目。我正在实现一个BeanFactoryPostProcessor动态创建我DataSource的 s。但问题是我DataSource的信息(姓名、网址等)存储在数据库本身中。

@Component 
class DatasourceRegisteringBeanFactoryPostProcessor implements BeanFactoryPostProcessor { 

  // This doesn't work
  @Autowired DatabaseService databaseService;

  public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // my code here ...
    // ...
  }
}

如您所见,我试图注入一项服务,该服务可以DataSource从我的数据库中获取所有 s 的列表,但它不起作用。无论如何要连接到数据库并在BeanFactoryPostProcessor类中获取该列表?欢迎任何其他解决方法。:)

4

1 回答 1

0

BeanFactoryPostProcessors 是 Spring 中一种非常特殊的概念。它们是对实例进行操作的组件,实例是要创建BeanDefinition的 bean 实例的元模型。

这意味着,在BFPP调用 s 的时间点,还没有创建任何 bean 实例,因为元模型即将进行后处理(顾名思义)。因此,依赖于 bean 的 beanBFPP将在容器生命周期的早期初始化。因此,强烈建议不要依赖BFPPs 中的应用程序组件,或者——如果确实需要——只依赖于不一定会触发创建大量下游组件的 bean。

也就是说,您不应该特别依赖BFPPs 中的存储库,因为它们通常需要创建大量基础架构组件。我建议获取连接到配置数据库所需的配置属性(JDBC URL、用户名、密码等),并创建一个只用于为将要使用的新DataSource创建一个新的丢弃最终由应用程序。BeanDefinitionDataSource

所以这里是推荐的步骤(从我的头顶 - 可能需要一些调整):

  • 放弃 a 的自动装配DataSource
  • 配置@PropertySource指向包含要连接的坐标的属性
  • 将其值注入PropertySource到的构造函数中BFPP

    class YourBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    
      public YourBeanFactoryPostProcessor(@Value("#{properties.url}) String url, …) {
        // assign to fields
      }
    
      public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    
        // 1. Create throw-away DataSource
        // 2. Create JdbcTemplate
        // 3. Use template to lookup configuration properties
        // 4. Create BeanDefinition for DataSource using properties just read
        // 5. Register BeanDefinition with the BeanFactory
      }
    }
    
于 2014-10-07T20:15:33.487 回答