001/* 002 * Copyright 2012-2018 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.boot.autoconfigure.data.jpa; 018 019import javax.sql.DataSource; 020 021import org.springframework.beans.factory.ObjectProvider; 022import org.springframework.boot.autoconfigure.AutoConfigureAfter; 023import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 024import org.springframework.boot.autoconfigure.condition.AnyNestedCondition; 025import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; 026import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 027import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 028import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 029import org.springframework.boot.autoconfigure.orm.jpa.EntityManagerFactoryBuilderCustomizer; 030import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; 031import org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration; 032import org.springframework.context.annotation.Bean; 033import org.springframework.context.annotation.Conditional; 034import org.springframework.context.annotation.Configuration; 035import org.springframework.context.annotation.Import; 036import org.springframework.core.task.AsyncTaskExecutor; 037import org.springframework.data.jpa.repository.JpaRepository; 038import org.springframework.data.jpa.repository.config.EnableJpaRepositories; 039import org.springframework.data.jpa.repository.config.JpaRepositoryConfigExtension; 040import org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean; 041 042/** 043 * {@link EnableAutoConfiguration Auto-configuration} for Spring Data's JPA Repositories. 044 * <p> 045 * Activates when there is a bean of type {@link javax.sql.DataSource} configured in the 046 * context, the Spring Data JPA 047 * {@link org.springframework.data.jpa.repository.JpaRepository} type is on the classpath, 048 * and there is no other, existing 049 * {@link org.springframework.data.jpa.repository.JpaRepository} configured. 050 * <p> 051 * Once in effect, the auto-configuration is the equivalent of enabling JPA repositories 052 * using the {@link org.springframework.data.jpa.repository.config.EnableJpaRepositories} 053 * annotation. 054 * <p> 055 * This configuration class will activate <em>after</em> the Hibernate auto-configuration. 056 * 057 * @author Phillip Webb 058 * @author Josh Long 059 * @see EnableJpaRepositories 060 */ 061@Configuration 062@ConditionalOnBean(DataSource.class) 063@ConditionalOnClass(JpaRepository.class) 064@ConditionalOnMissingBean({ JpaRepositoryFactoryBean.class, 065 JpaRepositoryConfigExtension.class }) 066@ConditionalOnProperty(prefix = "spring.data.jpa.repositories", name = "enabled", havingValue = "true", matchIfMissing = true) 067@Import(JpaRepositoriesAutoConfigureRegistrar.class) 068@AutoConfigureAfter({ HibernateJpaAutoConfiguration.class, 069 TaskExecutionAutoConfiguration.class }) 070public class JpaRepositoriesAutoConfiguration { 071 072 @Bean 073 @Conditional(BootstrapExecutorCondition.class) 074 public EntityManagerFactoryBuilderCustomizer entityManagerFactoryBootstrapExecutorCustomizer( 075 ObjectProvider<AsyncTaskExecutor> taskExecutor) { 076 return (builder) -> builder.setBootstrapExecutor(taskExecutor.getIfAvailable()); 077 } 078 079 private static final class BootstrapExecutorCondition extends AnyNestedCondition { 080 081 BootstrapExecutorCondition() { 082 super(ConfigurationPhase.REGISTER_BEAN); 083 } 084 085 @ConditionalOnProperty(prefix = "spring.data.jpa.repositories", name = "bootstrap-mode", havingValue = "deferred", matchIfMissing = false) 086 static class DeferredBootstrapMode { 087 088 } 089 090 @ConditionalOnProperty(prefix = "spring.data.jpa.repositories", name = "bootstrap-mode", havingValue = "lazy", matchIfMissing = false) 091 static class LazyBootstrapMode { 092 093 } 094 095 } 096 097}