使用Spring注释读取文件属性

我正在尝试学习如何使用spring读取属性文件。 在互联网搜索后,我发现我可以使用@value@PropertySource注释来实现这一点。 我创建了一个具有以下结构和类代码的项目:

项目结构:

在此处输入图像描述

AppConfigMongoDB.java实现:

 package com.mongodb.properties; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.PropertySource; @PropertySource("classpath:config/config.properties") public class AppConfigMongoDB { @Value("#{mongodb.url}") private String mongodbUrl; @Value("#{mongodb.db}") private String defaultDb; public String getMongoDb() { return defaultDb; } public String getMongoDbUrl() { return mongodbUrl; } } 

SpringConfiguration.java实现:

  package com.mongodb.properties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class SpringConfiguration { @Bean public AppConfigMongoDB getAppConfigMongoDB(){ return new AppConfigMongoDB(); } } 

Main.java

 package com.mongodb.properties; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class Main { public static void main(String[] args) { ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfiguration.class); AppConfigMongoDB mongo = applicationContext.getBean(AppConfigMongoDB.class); System.out.println("db= "+mongo.getMongoDb()); System.out.println("URL= "+mongo.getMongoDbUrl()); } } 

我正在读取的属性文件名为config.properties,它包含以下行:

 mongodb.url=1.2.3.4 mongodb.db=dataBase 

我测试了这个小项目,我得到了一个包含以下exception的堆栈跟踪:

 org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'getAppConfigMongoDB': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private java.lang.String com.mongodb.properties.AppConfigMongoDB.mongodbUrl; nested exception is org.springframework.beans.factory.BeanExpressionException: Expression parsing failed; nested exception is org.springframework.expression.spel.SpelEvaluationException: EL1008E:(pos 0): Property or field 'mongodb' cannot be found on object of type 'org.springframework.beans.factory.config.BeanExpressionContext' - maybe not public? at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1202) 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.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:755) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480) at org.springframework.context.annotation.AnnotationConfigApplicationContext.(AnnotationConfigApplicationContext.java:84) at com.mongodb.properties.Main.main(Main.java:9) Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1008E:(pos 0): Property or field 'mongodb' cannot be found on object of type 'org.springframework.beans.factory.config.BeanExpressionContext' - maybe not public? at org.springframework.expression.spel.ast.PropertyOrFieldReference.readProperty(PropertyOrFieldReference.java:226) at org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:93) at org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:81) at org.springframework.expression.spel.ast.CompoundExpression.getValueRef(CompoundExpression.java:51) at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:87) at org.springframework.expression.spel.ast.SpelNodeImpl.getValue(SpelNodeImpl.java:120) at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:242) at org.springframework.context.expression.StandardBeanExpressionResolver.evaluate(StandardBeanExpressionResolver.java:161) ... 18 more 

这是Spring调用bean的问题吗? 或者可能是属性文件路径或其他问题?

我可以在代码中看到几个问题。

1)你的价值持有人应该是${mogodb.url} ,而不是#{mongodb.url} 。 “#”具有不同的含义(参见Spring Expressions )。

2)您将需要一个PropertySourcesPlaceholderConfigurer bean来执行值的注入

3)迟早你会有一些豆子漂浮在周围,我会使用@ComponentScan让上下文知道这些,而你不必一个一个地提到它们

4)如果使用ComponentScan获取bean,则必须提供一次AppConfigMongoDB bean

在完成所有这些后,我最终得到了这些类:

Main.java

 import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class Main { public static void main(String[] args) { ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfiguration.class); AppConfigMongoDB mongo = applicationContext.getBean(AppConfigMongoDB.class); System.out.println("db= "+mongo.getMongoDb()); System.out.println("URL= "+mongo.getMongoDbUrl()); } } 

SpringConfiguration.java

 import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; @Configuration @ComponentScan public class SpringConfiguration { @Bean public static PropertySourcesPlaceholderConfigurer propertyConfigInDev() { return new PropertySourcesPlaceholderConfigurer(); } } 

AppConfigMongoDB.java

 import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; @Configuration @PropertySource("classpath:config/config.properties") public class AppConfigMongoDB { @Value("${mongodb.url}") private String mongodbUrl; @Value("${mongodb.db}") private String defaultDb; public String getMongoDb() { return defaultDb; } public String getMongoDbUrl() { return mongodbUrl; } } 

@Ian Sparkes给出了很好的回复。 在这里添加一些我的输入。 配置PropertySourcesPlaceholderConfigurer不是必需的。 我可以从我的属性文件中获取值,并将其设置为我的主要Configuration类的字段变量,而不是它。

还有另一种方法可以在属性文件中获取键的值。 使用org.springframework.core.env.Environment类。 此类自动加载类路径中的属性文件中的所有键值对。

示例:

 @Configuration @ComponentScan(basePackages="com.easy.buy") @PropertySource({"classpath:config.properties","classpath:props/db-${env}-config.properties", "classpath:props/app-${env}-config.properties"}) public class CatalogServiceConfiguration { Logger logger = LoggerFactory.getLogger(CatalogServiceConfiguration.class); //This object loads & holds all the properties in it as key-pair values @Autowired private Environment env; /** * Instantiate the DataSource bean & initialize it with db connection properties * @return */ @Bean(name="basicDataSource") public BasicDataSource basicDataSource() { String dbUrl = env.getProperty("db.url"); String dbUser = env.getProperty("db.user"); String dbPwd = env.getProperty("db.pwd"); String driver = env.getProperty("db.driver"); logger.info("Initializing CatalogServiceConfiguration"); logger.info("dbUrl=" + dbUrl); BasicDataSource ds = new BasicDataSource(); ds.setDriverClassName(driver); ds.setUrl(dbUrl); ds.setUsername(dbUser); ds.setPassword(dbPwd); return ds; } }