java - Spring 配置文件 org.springframework.beans.factory.NoSuchBeanDefinitionException

标签 java spring maven spring-mvc spring-profiles

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

我真正的疑问是:我已经在 application.properties 文件中很好地配置了 spring 属性,但为什么它找不到配置文件及其各自的属性文件?除非我使用 @PropertySource注释,iam 没有获取 env.getProperty("mysql.url") 的值。我的意思是Environment类无法从配置文件属性文件中获取值。 为什么?

我收到如下错误:

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;
    }
}

Main2.java

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);


    }

}

application.properties

spring.profiles.active=prod
spring.config.name=application
spring.config.location=classpath:/application.properties,classpath:/dev/application-dev.properties,classpath:/prod/application-dev.properties

以下是项目文件夹结构:

enter image description here

请告诉我出了什么问题?

最佳答案

Spring很聪明,它根据application.properties中分配给spring.profiles.active的值来选择application-x.properties(其中x是环境),所以你不必担心注册所有不同@PropertySource注释中的文件。

您可以在此处获取更多信息:https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-profile-specific-properties

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

如果你想为特定的配置文件(比如说dev)定义一个mysql.url,你需要在application-dev.properties文件中添加“mysql.url”,然后设置spring.profiles.active application.properties 中 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;
}

请告诉我这对您有用。

关于java - Spring 配置文件 org.springframework.beans.factory.NoSuchBeanDefinitionException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44987287/

相关文章:

Java - 正则表达式将第一个和最后一个字符一次性替换为另一个字符

java - 带有空参数的 Spring 数据 jpa native 查询(PostgreSQL)

java - 跟踪 Pub-Sub 模型中的请求开始和结束 - 问题

java - 如何让javadoc检查器不那么严格?

java - 不要将 gradle 子项目安装为外部依赖项

java - 使用 JSF 和 primefaces 的无序列表 (ul)

java - 复选框显示?

Spring Boot 设置 SSL 连接报错

java - 如何部署/检索模块化 Maven 项目的模块版本信息?

java - Android 特定的通过在谓词上匹配集合中的属性来查找对象