Spring Boot不要在启动时建立JPA数据库连接

时间:2014-12-12 21:08:03

标签: java jpa groovy spring-boot hibernate-4.x

我有一个Spring Boot + Groovy应用程序,需要按会话或每个租户进行数据库连接。 使用Hibernate实现解决方案时,只有它可以正常工作,但是当添加spring-boot-starter-data-jpa并切换到JPA时,尝试启动数据库连接失败,因为尚未定义连接设置。

我有一个gradle依赖项块,如下所示:

dependencies {
    compile "org.springframework.boot:spring-boot-starter-web"
    compile "org.springframework.boot:spring-boot-starter-data-jpa"

    compile "org.codehaus.groovy:groovy-all:2.3.3"

    compile "org.springframework:spring-core:${springVersion}"
    compile "org.springframework:spring-webmvc:${springVersion}"
    compile "org.springframework:spring-orm:${springVersion}"
    compile "org.springframework:spring-aop:${springVersion}"
    compile "org.springframework:spring-context-support:${springVersion}"
    compile "org.hibernate:hibernate-entitymanager:${hibernateVersion}"
    compile "com.oracle:ojdbc7:12.1.0.1"
    compile "org.apache.commons:commons-dbcp2:2.0.1"
    compile "cglib:cglib:3.1"
...
}

我的Application.groovy看起来像这样:

@Configuration
@EnableAutoConfiguration
@ComponentScan
@EnableTransactionManagement
class Application
{
    final Logger aLog = Logger.getLogger(Application.class)

    @Autowired
    DatabaseSettings dbSettings

    @Bean(destroyMethod="close")
    @Lazy
    public DataSource dataSource()
    {
        aLog.info ">>>>>>>>>>>>> CREATING DATA SOURCE <<<<<<<<<<<<<<<"
        new BasicDataSource(driverClassName: dbSettings.driverClassName,    
                            url: dbSettings.dbUrl, username: dbSettings.dbUser, password: dbSettings.dbPass, 
                            maxTotal: 10, maxWaitMillis: 10000, maxIdle:10, defaultAutoCommit:false)
    }

    @Bean
    @Lazy
    public LocalContainerEntityManagerFactoryBean entityManagerFactory()
    {
        Properties hqlProps =   ['hibernate.dialect': this.dbSettings.dialect, 'hibernate.temp.use_jdbc_metadata_defaults': false,
                                 'hibernate.show_sql': this.dbSettings.showSql, 'hibernate.format_sql': this.dbSettings.formatSql, 
                                 'hibernate.use_sql_comments': this.dbSettings.useSqlComments] as Properties

        aLog.info ">>>>>>>>>>>>> CREATING ENTITY MANAGER FACTORY <<<<<<<<<<<<<<<"

        LocalContainerEntityManagerFactoryBean em   =   new LocalContainerEntityManagerFactoryBean()

        em.setDataSource(dataSource())
        em.setPackagesToScan(this.dbSettings.getPackagesToScan())
        em.setJpaVendorAdapter(new HibernateJpaVendorAdapter())
        em.setJpaProperties(hqlProps)
        em
    }

    @Bean
    @Lazy
    public JpaTransactionManager transactionManager()
    {
        aLog.info ">>>>>>>>>>>>> CREATING TRANSACTION MANAGER <<<<<<<<<<<<<<<"
        new JpaTransactionManager(entityManagerFactory: entityManagerFactory().getObject())     
    }

    static void main(args) throws Exception
    {
        ApplicationContext appCtx = SpringApplication.run(Application.class, args)
    }
}

为简单起见,我删除了Scopes配置。

重点是所有相关的Beans都注释为@Lazy,但是在启动时我会看到有关正在创建数据源和实体管理器的消息。

调试代码看起来在某些时候调用HibernateJpaAutoConfigurer并且这个类具有@Autowired DataSource,从而导致在启动时实例化这些bean。

我的问题是:如何阻止Spring Boot在启动时尝试数据库连接?

提前致谢

2 个答案:

答案 0 :(得分:0)

我想我找到了一个解决方法:

看看spring-boot-starte-data-jpa的pom.xml我发现它依赖于spring-data-jpa,所以我决定用spring-data替换starter-data-jpa- jpa有部分结果。 我仍然无法获得会话范围或自定义范围来延迟组件的初始化,它甚至无法实际编译。 因此,为了让一切工作变得更好,我也需要所有的方面也是如此。

所以现在我的依赖关系看起来像:

dependencies {
compile "org.springframework.boot:spring-boot-starter-web"
// 
compile "org.springframework.data:spring-data-jpa:1.7.1.RELEASE"
compile "org.aspectj:aspectjweaver:1.8.4"

compile "org.codehaus.groovy:groovy-all:2.3.3"
... }

因此,如果现在我使用@Scope(值=&#34;会话&#34;,proxyMode = ScopedProxyMode.TARGET_CLASS)或甚至使用自定义范围来注释DataSource创建,则实例化将在启动过程之后发生,如预期的那样。

然而,感觉就像打败使用SpringBoot的目的一样,我仍然认为应该有一种方法来配置SpringBoot,以便我可以获得相同的结果。

答案 1 :(得分:0)

就我的问题而言,您希望在启动时自动装配数据源,这是在使用@EnableAutoConfiguration时完成的。要配置数据库连接,例如要随时保留的连接数,可以使用

之类的属性
spring.datasource.initialSize
spring.datasource.maxActive
spring.datasource.maxIdle
spring.datasource.minIdle

对于您的情况,您可以将spring.datasource.maxIdle定义为0,以便没有空闲连接,然后您可以按需使用连接。有关详细信息,请参阅http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html