Spring boot - 数据源配置

时间:2015-10-18 17:20:08

标签: spring-boot spring-data

在我的项目中使用Spring Boot 1.2.7版。计划使用Spring Data JPA并尝试设置通用连接池来为mysql JDBC设置数据源。

收到以下错误,无法设置数据源。

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private javax.sql.DataSource org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration.dataSource; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [javax.sql.DataSource] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1210)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:368)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1119)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1014)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:956)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:747)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:117)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:689)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:321)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:969)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:958)
    at mymantri.MymantriApplication.main(MymantriApplication.java:13)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private javax.sql.DataSource org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration.dataSource; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [javax.sql.DataSource] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:561)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
    ... 25 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [javax.sql.DataSource] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1301)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1047)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:533)
    ... 27 more

我的pom.xml,

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.test</groupId>
    <artifactId>test</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>test</name>
    <description>Test</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.2.7.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <start-class>test.TestApplication</start-class>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jersey</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.inject</groupId>
            <artifactId>javax.inject</artifactId>
        </dependency>
        <dependency>
            <groupId>com.oracle</groupId>
            <artifactId>ucp</artifactId>
            <version>11.2.0.3</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpcore</artifactId>
            <version>4.4</version>
        </dependency>
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.4</version>
        </dependency>
        <dependency>
            <groupId>commons-collections</groupId>
            <artifactId>commons-collections</artifactId>
        </dependency>
        <dependency>
            <groupId>com.eaio.uuid</groupId>
            <artifactId>uuid</artifactId>
            <version>3.2</version>
        </dependency>
        <dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-core-asl</artifactId>
            <version>1.9.13</version>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
        </dependency>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
        </dependency>
        <dependency>
            <groupId>net.sf.json-lib</groupId>
            <artifactId>json-lib</artifactId>
            <version>2.4</version>
            <classifier>jdk15</classifier>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-parent</artifactId>
                <version>Angel.SR3</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>


</project>

TestApplication.java,

@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, VelocityAutoConfiguration.class })
public class TestApplication {

    public static void main(String[] args) {
        SpringApplication.run(TestApplication.class, args);
    }
}

application-dev.properties,

application.datasource.driverClassName=com.mysql.jdbc.jdbc2.optional.MysqlDataSource
application.datasource.url=jdbc:mysql://localhost:3306/mymantri
application.datasource.username=root
application.datasource.password=root
application.datasource.initialSize=5
application.datasource.maxPoolSize=5
application.datasource.minPoolSize=5

hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
spring.jpa.properties.hibernate.dialect= org.hibernate.dialect.MySQL5Dialect

DataSource类,

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(entityManagerFactoryRef = "testEntityManagerFactory", transactionManagerRef = "testTransactionManager", basePackages = { "com.mymantri.web.repository"})
public class ApplicationDataSource {

    /** The Constant LOGGER. */
    private static final Logger LOGGER = LoggerFactory
            .getLogger(ApplicationDataSource.class);

    /** The Constant TEST_SQL. */
    private static final String TEST_SQL = "select 1 from dual";

    /** The pooled data source. */
    private PoolDataSource pooledDataSource;


    /** The environment. */
    private Environment environment;

    /** The Constant CONNECTION_WAIT_TIMEOUT_SECS. */
    private static final int CONNECTION_WAIT_TIMEOUT_SECS = 300;

    /**
     * Data source.
     * 
     * @return the pool data source
     */
    @Bean(name = "testDataSource")
    @Primary
    public PoolDataSource testDataSource() {

        this.pooledDataSource = PoolDataSourceFactory.getPoolDataSource();
        final String databaseDriver = environment
                .getRequiredProperty("application.datasource.driverClassName");
        final String databaseUrl = environment
                .getRequiredProperty("application.datasource.url");
        final String databaseUsername = environment
                .getRequiredProperty("application.datasource.username");
        final String databasePassword = environment
                .getRequiredProperty("application.datasource.password");
        final String initialSize = environment
                .getRequiredProperty("application.datasource.initialSize");
        final String maxPoolSize = environment
                .getRequiredProperty("application.datasource.maxPoolSize");
        final String minPoolSize = environment
                .getRequiredProperty("application.datasource.minPoolSize");

        try {
            pooledDataSource.setConnectionFactoryClassName(databaseDriver);
            pooledDataSource.setURL(databaseUrl);
            pooledDataSource.setUser(databaseUsername);
            pooledDataSource.setPassword(databasePassword);
            pooledDataSource.setInitialPoolSize(Integer.parseInt(initialSize));
            pooledDataSource.setMaxPoolSize(Integer.parseInt(maxPoolSize));
            pooledDataSource.setMinPoolSize(Integer.parseInt(minPoolSize));
            pooledDataSource.setSQLForValidateConnection(TEST_SQL);
            pooledDataSource.setValidateConnectionOnBorrow(Boolean.TRUE);
            pooledDataSource
                    .setConnectionWaitTimeout(CONNECTION_WAIT_TIMEOUT_SECS);
            // pooledDataSource.setConnectionPoolName(poolName);
        } catch (NumberFormatException e) {
            LOGGER.error("Unable to parse passed numeric value", e);
        } catch (SQLException e) {
            LOGGER.error("exception creating data pool", e);
        }

        LOGGER.info("Setting up datasource for user:{} and databaseUrl:{}",
                databaseUsername, databaseUrl);
        return this.pooledDataSource;
    }

    @Bean(name = "testEntityManagerFactory")
    public EntityManagerFactory entityManagerFactory() {
        LocalContainerEntityManagerFactoryBean lef = new LocalContainerEntityManagerFactoryBean();
        JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        lef.setDataSource(myMantriDataSource());
        lef.setJpaVendorAdapter(vendorAdapter);
        lef.setPackagesToScan("com.mymantri.web.domain");
        lef.setJpaProperties(additionalProperties());
        lef.setPersistenceUnitName("myMantriPersistenceUnit");
        lef.afterPropertiesSet();
        return lef.getObject();
    }

    @Bean(name = "testTransactionManager")
    public PlatformTransactionManager transactionManager() {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(entityManagerFactory());
        return transactionManager;
    }

    Properties additionalProperties() {
        Properties properties = new Properties();
        properties.setProperty("hibernate.dialect",
                "org.hibernate.dialect.MySQL5Dialect"); 
        properties.setProperty("hibernate.enable_lazy_load_no_trans",
                "true");    
        properties.setProperty("hibernate.show_sql","true");

        return properties;
    }

    /**
     * Sets the environment.
     * 
     * @param environment
     *            the new environment
     */
    @Autowired
    public void setEnvironment(Environment environment) {

        this.environment = environment;
    }

}

不确定,此配置有什么问题。我错过了SpringBootConfig配置中的任何内容。

2 个答案:

答案 0 :(得分:0)

尝试更改数据源注册方法签名:

@Bean
public DataSource dataSource() {
顺便说一句,在配置类中使用局部变量并不是一个好主意。您有environmentpooledDataSource。删除这些类变量并在方法中本地创建它们+通过@Bean注释将它们传递给Spring IoC容器。

我建议至少以这种方式更改配置类:

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(entityManagerFactoryRef = "testEntityManagerFactory", transactionManagerRef = "testTransactionManager", basePackages = { "com.mymantri.web.repository"})
public class ApplicationDataSource {

    /** The Constant LOGGER. */
    private static final Logger LOGGER = LoggerFactory
            .getLogger(ApplicationDataSource.class);

    /** The Constant TEST_SQL. */
    private static final String TEST_SQL = "select 1 from dual";

    /** The Constant CONNECTION_WAIT_TIMEOUT_SECS. */
    private static final int CONNECTION_WAIT_TIMEOUT_SECS = 300;

    /**
     * Data source.
     * 
     * @return the pool data source
     */
    @Bean
    public DataSource dataSource(Environment environment) {

        PoolDataSource pooledDataSource = PoolDataSourceFactory.getPoolDataSource();
        final String databaseDriver = environment
                .getRequiredProperty("application.datasource.driverClassName");
        final String databaseUrl = environment
                .getRequiredProperty("application.datasource.url");
        final String databaseUsername = environment
                .getRequiredProperty("application.datasource.username");
        final String databasePassword = environment
                .getRequiredProperty("application.datasource.password");
        final String initialSize = environment
                .getRequiredProperty("application.datasource.initialSize");
        final String maxPoolSize = environment
                .getRequiredProperty("application.datasource.maxPoolSize");
        final String minPoolSize = environment
                .getRequiredProperty("application.datasource.minPoolSize");

        try {
            pooledDataSource.setConnectionFactoryClassName(databaseDriver);
            pooledDataSource.setURL(databaseUrl);
            pooledDataSource.setUser(databaseUsername);
            pooledDataSource.setPassword(databasePassword);
            pooledDataSource.setInitialPoolSize(Integer.parseInt(initialSize));
            pooledDataSource.setMaxPoolSize(Integer.parseInt(maxPoolSize));
            pooledDataSource.setMinPoolSize(Integer.parseInt(minPoolSize));
            pooledDataSource.setSQLForValidateConnection(TEST_SQL);
            pooledDataSource.setValidateConnectionOnBorrow(Boolean.TRUE);
            pooledDataSource
                    .setConnectionWaitTimeout(CONNECTION_WAIT_TIMEOUT_SECS);
            // pooledDataSource.setConnectionPoolName(poolName);
        } catch (NumberFormatException e) {
            LOGGER.error("Unable to parse passed numeric value", e);
        } catch (SQLException e) {
            LOGGER.error("exception creating data pool", e);
        }

        LOGGER.info("Setting up datasource for user:{} and databaseUrl:{}",
                databaseUsername, databaseUrl);
        return pooledDataSource;
    }

    @Bean
    public EntityManagerFactory entityManagerFactory() {
        LocalContainerEntityManagerFactoryBean lef = new LocalContainerEntityManagerFactoryBean();
        JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        lef.setDataSource(myMantriDataSource());
        lef.setJpaVendorAdapter(vendorAdapter);
        lef.setPackagesToScan("com.mymantri.web.domain");
        lef.setJpaProperties(additionalProperties());
        lef.setPersistenceUnitName("myMantriPersistenceUnit");
        lef.afterPropertiesSet();
        return lef.getObject();
    }

    @Bean
    public PlatformTransactionManager transactionManager() {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(entityManagerFactory());
        return transactionManager;
    }

    Properties additionalProperties() {
        Properties properties = new Properties();
        properties.setProperty("hibernate.dialect",
                "org.hibernate.dialect.MySQL5Dialect"); 
        properties.setProperty("hibernate.enable_lazy_load_no_trans",
                "true");    
        properties.setProperty("hibernate.show_sql","true");

        return properties;
    }

}

答案 1 :(得分:0)

将应用程序移动到com.XXXXXX.web包。

com.XXXXXX.web.domain - 适用于域类 com.XXXXXX.web.repository - 用于存储库类

默认注释扫描基于Application类包名称进行。