我有一个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在启动时尝试数据库连接?
提前致谢
答案 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。