我的示例项目是基于Maven的结构,我的所有应用程序都在src/main/resources
文件夹下提供文件。以下是完整的示例代码。我不明白为什么我的代码无法正确查找配置文件,除非我使用@PropertySource
注释。
我的实际疑问是:我已经在application.properties文件中很好地配置了spring属性,但是为什么它找不到配置文件及其各自的属性文件呢?除非我使用@PropertySource
注释,否则我没有获得env.getProperty(“mysql.url”)的值。我的意思是Environment
类无法从配置文件属性文件中获取值。的 WHY吗
我收到如下错误:
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
以下是项目文件夹结构:
请告诉我出了什么问题?
答案 0 :(得分:1)
Spring很聪明,它选择application-x.properties(其中x是环境),具体取决于application.properties中分配给spring.profiles.active的值,因此您不必担心全部注册不同的@PropertySource注释中的文件。
我建议你删除所有@Profile注释,只放一个可变的数据源(取决于application.properties中的seleced环境)。您可以通过我在本文末尾提供的示例来理解这一点。
如果要为特定的配置文件定义mysql.url(比方说dev),则需要在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;
}
请让我知道这对你有用。
答案 1 :(得分:0)
@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 load 1)application.property,2)pplication-dev / prod.properties文件,带有来自application.property的覆盖值
答案 2 :(得分:0)
我已经解决了我的问题,只需修改如下:
@PropertySource("classpath:/${spring.profiles.active}/application-${spring.profiles.active}.properties")
现在我可以动态地拾取application-dev.properties(或)application-prod.properties。
注意:Environment
类需要@PropertySource注释,否则我们为env.get('someproperty')获取null。