Java Spring概要文件org.springframework.beans.factory.NoSuchBeanDefinitionException

Java Spring概要文件org.springframework.beans.factory.NoSuchBeanDefinitionException,java,spring,maven,spring-mvc,spring-profiles,Java,Spring,Maven,Spring Mvc,Spring Profiles,我的示例项目是基于Maven的结构,我的所有应用程序项目都位于src/main/resources文件夹下。下面是完整的示例代码。我不明白为什么我的代码不能正确地找到配置文件,除非我使用@PropertySource注释 我真正的疑问是:我已经在application.properties文件中很好地配置了spring属性,但为什么它找不到概要文件及其各自的属性文件呢?除非我使用@PropertySourceannotation,否则我将无法获取env.getProperty(“mysql.ur

我的示例项目是基于Maven的结构,我的所有应用程序项目都位于
src/main/resources
文件夹下。下面是完整的示例代码。我不明白为什么我的代码不能正确地找到配置文件,除非我使用
@PropertySource
注释

我真正的疑问是:我已经在application.properties文件中很好地配置了spring属性,但为什么它找不到概要文件及其各自的属性文件呢?除非我使用
@PropertySource
annotation,否则我将无法获取env.getProperty(“mysql.url”)的值。我的意思是
环境
类无法从配置文件属性文件中提取值为什么?

我收到如下错误:

Jul 08, 2017 7:54:26 PM org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@300ffa5d: startup date [Sat Jul 08 19:54:26 IST 2017]; root of context hierarchy
helloBean
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'datasource' available
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:687)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1207)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:284)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1084)
    at com.oreilly.datasource.Main2.main(Main2.java:15)
DatasourceConfig.java

package com.oreilly.datasource;

import javax.sql.DataSource;

import org.apache.commons.dbcp.BasicDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.annotation.PropertySources;
import org.springframework.core.env.Environment;

@Configuration
/*@PropertySource("classpath:/application.properties")
@PropertySource("classpath:/dev/application-dev.properties")
@PropertySource("classpath:/prod/application-prod.properties")*/
public class DatasourceConfig {

    @Autowired
    private Environment env;

    @Bean(name="helloBean")
    public String helloWorld() {
        System.out.println("helloBean");
        return "helloWorld....";
    }

    @Bean(name="datasource")
    @Profile("dev")
    public DataSource datasourceForDev(){
        BasicDataSource dataSource = new BasicDataSource();
        System.out.println(env.getProperty("mysql.url"));
        return dataSource;
    }

    @Bean(name="datasource")
    @Profile("prod")
    public DataSource datasourceForProd(){
        BasicDataSource dataSource = new BasicDataSource();
        System.out.println(env.getProperty("mysql.url"));
        return dataSource;
    }
}
package com.oreilly.datasource;

import javax.sql.DataSource;

import org.apache.commons.dbcp.BasicDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Main2 {


    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(DatasourceConfig.class);

        DataSource dataSource = context.getBean("datasource", DataSource.class);
        String helloBean = context.getBean("helloBean", String.class);


    }

}
Main2.java

package com.oreilly.datasource;

import javax.sql.DataSource;

import org.apache.commons.dbcp.BasicDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.annotation.PropertySources;
import org.springframework.core.env.Environment;

@Configuration
/*@PropertySource("classpath:/application.properties")
@PropertySource("classpath:/dev/application-dev.properties")
@PropertySource("classpath:/prod/application-prod.properties")*/
public class DatasourceConfig {

    @Autowired
    private Environment env;

    @Bean(name="helloBean")
    public String helloWorld() {
        System.out.println("helloBean");
        return "helloWorld....";
    }

    @Bean(name="datasource")
    @Profile("dev")
    public DataSource datasourceForDev(){
        BasicDataSource dataSource = new BasicDataSource();
        System.out.println(env.getProperty("mysql.url"));
        return dataSource;
    }

    @Bean(name="datasource")
    @Profile("prod")
    public DataSource datasourceForProd(){
        BasicDataSource dataSource = new BasicDataSource();
        System.out.println(env.getProperty("mysql.url"));
        return dataSource;
    }
}
package com.oreilly.datasource;

import javax.sql.DataSource;

import org.apache.commons.dbcp.BasicDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Main2 {


    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(DatasourceConfig.class);

        DataSource dataSource = context.getBean("datasource", DataSource.class);
        String helloBean = context.getBean("helloBean", String.class);


    }

}
应用程序属性

spring.profiles.active=prod
spring.config.name=application
spring.config.location=classpath:/application.properties,classpath:/dev/application-dev.properties,classpath:/prod/application-dev.properties
下面是项目文件夹结构:

Jul 08, 2017 7:54:26 PM org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@300ffa5d: startup date [Sat Jul 08 19:54:26 IST 2017]; root of context hierarchy
helloBean
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'datasource' available
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:687)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1207)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:284)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1084)
    at com.oreilly.datasource.Main2.main(Main2.java:15)

请告诉我出了什么问题?

@Configuration
@PropertySource("classpath:application.properties")
public class DatasourceConfig {
....
}
将属性文件放在与application.property相同的位置,并遵循命名约定application-{profile}.properties,如application-dev.properties、application-prod.properties



“我希望根据我在application.properties中声明的配置文件自动拾取属性文件。” :


使用-Dspring.profiles.active=dev/prod运行应用程序。Spring加载1)application.property,2)application dev/prod.properties文件,其中包含application.property的overides值

Spring是智能的,它根据application.properties中分配给Spring.profiles.active的值来选择application-x.properties(其中x是环境),因此,您不必担心在不同的@PropertySource注释中注册所有文件

您可以在此处获得更多信息:

我建议您删除所有@Profile注释,只保留一个可变的数据源(取决于application.properties中选择的环境)。你可以通过我在这篇文章末尾的例子来理解这一点

如果要为特定概要文件(比如dev)定义mysql.url,需要在application-dev.properties文件中添加“mysql.url”,然后在application.properties中将spring.profiles.active值设置为dev

然后,在DatasourceConfig.java中,您可以执行如下操作:

@Autowired
private Environment env;

//Takes the mysqlUrl from application-x.properties (where x is the value of spring.profiles.active that comes from application.properties)
@Value("${mysql.url}")
private String mysqlUrl;

@Bean(name="helloBean")...

@Bean(name="datasource")
public DataSource datasource() {
    BasicDataSource dataSource = new BasicDataSource();
    System.out.println(mySqlUrl); //This value is variable depending of the profile that you're pointing on.
    return dataSource;
}

请让我知道这对您很有用。

我已通过以下修改解决了我的问题:

@PropertySource("classpath:/${spring.profiles.active}/application-${spring.profiles.active}.properties")
现在我可以动态地拾取application-dev.properties(或application-prod.properties)


注意
环境
类需要@PropertySource注释,否则我们会为env.get('someproperty')获取null.

另一条注释:您需要在资源根目录中定义application.properties和application-x.properties文件,以便Spring自动检测它们。我认为您应该正确理解我的查询。。我们应该使用环境类,而不是像“mysql.url”那样声明每个属性变量。。。我已经使用@Profile annotation声明了两个配置文件(dev和prod),使用了两种方法。我希望根据我在application.properties中声明的配置文件自动提取属性文件。。有什么想法吗?如果不使用@PropertySource,应该如何工作?我的意思是它应该自动获取我的application-dev.properties,如何?