Merge branch '2.1.x'
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2012-2018 the original author or authors.
|
* Copyright 2012-2019 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -16,9 +16,10 @@
|
|||||||
|
|
||||||
package org.springframework.boot.autoconfigure.data.jpa;
|
package org.springframework.boot.autoconfigure.data.jpa;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
import org.springframework.beans.factory.ObjectProvider;
|
|
||||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.condition.AnyNestedCondition;
|
import org.springframework.boot.autoconfigure.condition.AnyNestedCondition;
|
||||||
@@ -72,8 +73,23 @@ public class JpaRepositoriesAutoConfiguration {
|
|||||||
@Bean
|
@Bean
|
||||||
@Conditional(BootstrapExecutorCondition.class)
|
@Conditional(BootstrapExecutorCondition.class)
|
||||||
public EntityManagerFactoryBuilderCustomizer entityManagerFactoryBootstrapExecutorCustomizer(
|
public EntityManagerFactoryBuilderCustomizer entityManagerFactoryBootstrapExecutorCustomizer(
|
||||||
ObjectProvider<AsyncTaskExecutor> taskExecutor) {
|
Map<String, AsyncTaskExecutor> taskExecutors) {
|
||||||
return (builder) -> builder.setBootstrapExecutor(taskExecutor.getIfAvailable());
|
return (builder) -> {
|
||||||
|
AsyncTaskExecutor bootstrapExecutor = determineBootstrapExecutor(
|
||||||
|
taskExecutors);
|
||||||
|
if (bootstrapExecutor != null) {
|
||||||
|
builder.setBootstrapExecutor(bootstrapExecutor);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private AsyncTaskExecutor determineBootstrapExecutor(
|
||||||
|
Map<String, AsyncTaskExecutor> taskExecutors) {
|
||||||
|
if (taskExecutors.size() == 1) {
|
||||||
|
return taskExecutors.values().iterator().next();
|
||||||
|
}
|
||||||
|
return taskExecutors
|
||||||
|
.get(TaskExecutionAutoConfiguration.APPLICATION_TASK_EXECUTOR_BEAN_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class BootstrapExecutorCondition extends AnyNestedCondition {
|
private static final class BootstrapExecutorCondition extends AnyNestedCondition {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2012-2018 the original author or authors.
|
* Copyright 2012-2019 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -31,12 +31,17 @@ import org.springframework.boot.autoconfigure.data.jpa.city.CityRepository;
|
|||||||
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration;
|
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
|
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration;
|
import org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration;
|
||||||
|
import org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration;
|
||||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.ComponentScan.Filter;
|
import org.springframework.context.annotation.ComponentScan.Filter;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.FilterType;
|
import org.springframework.context.annotation.FilterType;
|
||||||
|
import org.springframework.context.annotation.Import;
|
||||||
|
import org.springframework.core.task.SimpleAsyncTaskExecutor;
|
||||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||||
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
||||||
|
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||||
import org.springframework.transaction.PlatformTransactionManager;
|
import org.springframework.transaction.PlatformTransactionManager;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
@@ -52,8 +57,7 @@ public class JpaRepositoriesAutoConfigurationTests {
|
|||||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||||
.withConfiguration(AutoConfigurations.of(HibernateJpaAutoConfiguration.class,
|
.withConfiguration(AutoConfigurations.of(HibernateJpaAutoConfiguration.class,
|
||||||
JpaRepositoriesAutoConfiguration.class,
|
JpaRepositoriesAutoConfiguration.class,
|
||||||
PropertyPlaceholderAutoConfiguration.class,
|
PropertyPlaceholderAutoConfiguration.class))
|
||||||
TaskExecutionAutoConfiguration.class))
|
|
||||||
.withUserConfiguration(EmbeddedDataSourceConfiguration.class);
|
.withUserConfiguration(EmbeddedDataSourceConfiguration.class);
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -87,33 +91,76 @@ public class JpaRepositoriesAutoConfigurationTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenBootstrappingModeIsLazyBootstrapExecutorIsConfigured() {
|
public void whenBootstrappingModeIsLazyWithMultipleAsyncExecutorBootstrapExecutorIsConfigured() {
|
||||||
this.contextRunner.withUserConfiguration(TestConfiguration.class)
|
this.contextRunner
|
||||||
|
.withUserConfiguration(MultipleAsyncTaskExecutorConfiguration.class)
|
||||||
|
.withConfiguration(
|
||||||
|
AutoConfigurations.of(TaskExecutionAutoConfiguration.class,
|
||||||
|
TaskSchedulingAutoConfiguration.class))
|
||||||
.withPropertyValues("spring.data.jpa.repositories.bootstrap-mode=lazy")
|
.withPropertyValues("spring.data.jpa.repositories.bootstrap-mode=lazy")
|
||||||
.run((context) -> assertThat(
|
.run((context) -> assertThat(
|
||||||
context.getBean(LocalContainerEntityManagerFactoryBean.class)
|
context.getBean(LocalContainerEntityManagerFactoryBean.class)
|
||||||
.getBootstrapExecutor()).isNotNull());
|
.getBootstrapExecutor()).isEqualTo(
|
||||||
|
context.getBean("applicationTaskExecutor")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenBootstrappingModeIsLazyWithSingleAsyncExecutorBootstrapExecutorIsConfigured() {
|
||||||
|
this.contextRunner
|
||||||
|
.withUserConfiguration(SingleAsyncTaskExecutorConfiguration.class)
|
||||||
|
.withPropertyValues("spring.data.jpa.repositories.bootstrap-mode=lazy")
|
||||||
|
.run((context) -> assertThat(
|
||||||
|
context.getBean(LocalContainerEntityManagerFactoryBean.class)
|
||||||
|
.getBootstrapExecutor()).isEqualTo(
|
||||||
|
context.getBean("testAsyncTaskExecutor")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenBootstrappingModeIsDeferredBootstrapExecutorIsConfigured() {
|
public void whenBootstrappingModeIsDeferredBootstrapExecutorIsConfigured() {
|
||||||
this.contextRunner.withUserConfiguration(TestConfiguration.class)
|
this.contextRunner
|
||||||
|
.withUserConfiguration(MultipleAsyncTaskExecutorConfiguration.class)
|
||||||
|
.withConfiguration(
|
||||||
|
AutoConfigurations.of(TaskExecutionAutoConfiguration.class,
|
||||||
|
TaskSchedulingAutoConfiguration.class))
|
||||||
.withPropertyValues(
|
.withPropertyValues(
|
||||||
"spring.data.jpa.repositories.bootstrap-mode=deferred")
|
"spring.data.jpa.repositories.bootstrap-mode=deferred")
|
||||||
.run((context) -> assertThat(
|
.run((context) -> assertThat(
|
||||||
context.getBean(LocalContainerEntityManagerFactoryBean.class)
|
context.getBean(LocalContainerEntityManagerFactoryBean.class)
|
||||||
.getBootstrapExecutor()).isNotNull());
|
.getBootstrapExecutor()).isEqualTo(
|
||||||
|
context.getBean("applicationTaskExecutor")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenBootstrappingModeIsDefaultBootstrapExecutorIsNotConfigured() {
|
public void whenBootstrappingModeIsDefaultBootstrapExecutorIsNotConfigured() {
|
||||||
this.contextRunner.withUserConfiguration(TestConfiguration.class)
|
this.contextRunner
|
||||||
|
.withUserConfiguration(MultipleAsyncTaskExecutorConfiguration.class)
|
||||||
|
.withConfiguration(
|
||||||
|
AutoConfigurations.of(TaskExecutionAutoConfiguration.class,
|
||||||
|
TaskSchedulingAutoConfiguration.class))
|
||||||
.withPropertyValues("spring.data.jpa.repositories.bootstrap-mode=default")
|
.withPropertyValues("spring.data.jpa.repositories.bootstrap-mode=default")
|
||||||
.run((context) -> assertThat(
|
.run((context) -> assertThat(
|
||||||
context.getBean(LocalContainerEntityManagerFactoryBean.class)
|
context.getBean(LocalContainerEntityManagerFactoryBean.class)
|
||||||
.getBootstrapExecutor()).isNull());
|
.getBootstrapExecutor()).isNull());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableScheduling
|
||||||
|
@Import(TestConfiguration.class)
|
||||||
|
protected static class MultipleAsyncTaskExecutorConfiguration {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@Import(TestConfiguration.class)
|
||||||
|
protected static class SingleAsyncTaskExecutorConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public SimpleAsyncTaskExecutor testAsyncTaskExecutor() {
|
||||||
|
return new SimpleAsyncTaskExecutor();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@TestAutoConfigurationPackage(City.class)
|
@TestAutoConfigurationPackage(City.class)
|
||||||
protected static class TestConfiguration {
|
protected static class TestConfiguration {
|
||||||
|
|||||||
@@ -3841,7 +3841,8 @@ Spring Data JPA repositories support three different modes of bootstrapping: def
|
|||||||
deferred, and lazy. To enable deferred or lazy bootstrapping, set the
|
deferred, and lazy. To enable deferred or lazy bootstrapping, set the
|
||||||
`spring.data.jpa.repositories.bootstrap-mode` to `deferred` or `lazy` respectively. When
|
`spring.data.jpa.repositories.bootstrap-mode` to `deferred` or `lazy` respectively. When
|
||||||
using deferred or lazy bootstrapping, the auto-configured `EntityManagerFactoryBuilder`
|
using deferred or lazy bootstrapping, the auto-configured `EntityManagerFactoryBuilder`
|
||||||
will use the context's async task executor, if any, as the bootstrap executor.
|
will use the context's `AsyncTaskExecutor`, if any, as the bootstrap executor. If more
|
||||||
|
than one exists, the one named `applicationTaskExecutor` will be used.
|
||||||
|
|
||||||
TIP: We have barely scratched the surface of Spring Data JPA. For complete details, see
|
TIP: We have barely scratched the surface of Spring Data JPA. For complete details, see
|
||||||
the https://docs.spring.io/spring-data/jpa/docs/current/reference/html/[Spring Data JPA
|
the https://docs.spring.io/spring-data/jpa/docs/current/reference/html/[Spring Data JPA
|
||||||
|
|||||||
Reference in New Issue
Block a user